xcdev
xcdev

Reputation: 37

C: Prevent passed function parameter modification?

Disclaimer: I don't have a lot of experience with C, I've only been using it for around a week now

Disclaimer 2: The code included in this post has nothing to do with removing spaces from a string and is only used to demonstrate the issue I was encountering

I'm having an issue with creating a function to remove all spaces from a string. While there are countless examples on the internet, I can't seem to find one that, instead of modifying the passed parameter, returns a completely new value that can be then assigned to it's own variable. (Maybe I'm just using C wrong)

char *rep(char s[])
{
    s[5] = '\0';

    return s;
}

int main()
{
    char a[] = "this is a test";
    char *b = rep(a);

    printf("%s\n", b);
    printf("%s a", a);

    return 0;
}

My output returns the same value when printing a and b, but I want to be able to not modify the value of a, and instead assign it to a new variable.

Upvotes: 1

Views: 495

Answers (3)

4386427
4386427

Reputation: 44256

First a few about your code. Since b is a pointer pointing to a any changes to to a will also be visible through b. So as you say - you need a copy.

In C there is no way to return an array from a function. Instead you can allocate some dynamic memory which can be used just like an array and return a pointer to the dynamic memory.

Like:

// This function must be called with a valid C-style string
// The function will return a dynamic allocated string
// with a copy of the first 5 characters of the input.
// If the input is shorter than 5 characters, all characters is copied.
char* rep(char s[])
{
    char* res = calloc(6, 1);  // Allocate the maximu size, i.e. 6 chars
                               // The "wasted" memory in case of short
                               // input strings are little compared to
                               // the overhead of dynamic allocation
                               // so it doesn't matter with a little
                               // over-allocation
    assert(res != NULL);
    for (int i = 0; i < 5 && s[i] != '\0'; ++i) 
    {
        res[i] = s[i];
    }
    return res;
}

Remember that the caller must free the returned pointer when it isn't used anymore.

Upvotes: 2

Kitswas
Kitswas

Reputation: 1197

Using malloc

#include <stdio.h>
#include <stdlib.h>

char* rep(char s[])
{
    int l = 0;
    for (int i = 0; s[i] != 0 ; i++) {
        ++l;
    }//determines the length of the string
    char* str = (char*)malloc(l*sizeof(char));//allocates memory for the new string
    for (int i = 0; s[i] != 0 ; i++) {
        str[i] = s[i];
    }//copies contents of string s to str
    
    //your operations below
    str[5] = '\0';//anything you do here is your sole responsibility
    //your operations above
    return str;
}

int main()
{
    char a[] = "this is a test";
    char *b = rep(a);
    printf("%s\n", b);
    free(b);//remember to free the memory after use
    printf("%s a", a);
    return 0;
}

I have not used any library functions from string.h.

Upvotes: 0

0___________
0___________

Reputation: 67476

Arrays are passed by reference in C not by the value.

You need to duplicate it into a new string and modify the duplicated string. You can use strdup function. Remember to check if it was successful.

#include <string.h>
#include <stdio.h>

char *rep(char s[])
{
    char *n = strdup(s);
    if(n) n[5] = '\0';

    return n;
}

int main(void)
{
    char a[] = "this is a test";
    char *b = rep(a);

    printf("%s\n", b ? b : "strdup failed");
    printf("%s a", a);

    free(b);

    return 0;
}

Upvotes: 2

Related Questions