Search code examples
cc-strings

C code not Behaving as Expected - C Strings - Removing Commas


I am perplexed that the following code is not behaving as expected.

The code behaves differently depending on how the string is initially defined (i.e. char str[] = "1,000" vs char *str = "1,000").

Here is the code:

#include <stdio.h>

char* removeCommasInString (char *str);

int main()
{
    char str[] = "1,000,000";
    char str2[] = "10,000";
    char* str3 = "1,000";
    
    printf("str is %s\n", str);
    printf("str is %s\n\n", removeCommasInString(str));
    
    printf("str2 is %s\n", str2);
    printf("str2 is %s\n\n", removeCommasInString(str2));
    
    printf("str3 is %s\n", str3);
    printf("str3 is %s\n", removeCommasInString(str3));
   
    puts("Program has ended");

    return 0;
}

char* removeCommasInString (char *str)
{
    const char *r = str;    // r is the read pointer
    char *w = str;          // w is the write pointer
                                                
    do {
        if (*r != ',')   
                         
        {
            *w++ = *r;   // Set *w (a single character in the string) to *r
        }
    } while (*r++);      // At end of the string, *r++ will be '\0' or 0 or false
                         // Then loop will end
                         // The str string will now have all the commas removed!!
                         // The str pointer still points to the beginning of the
                         // string.
                             
    return str;
}

Here is the output I get:

str is 1,000,000
str is 1000000

str2 is 10,000
str2 is 10000

str3 is 1,000


...Program finished with exit code 0
Press ENTER to exit console.

The commas are not removed in str3. And the main() function never reaches the "puts" statement. And I never see an error message.

I am sure it is something simple that I am missing.


Solution

  • char* str3 = "1,000";
    

    is basically the same as

    char* str3 = (char*)"1,000";
    

    since it is pointing to a string litteral (const char*), whereas the others allocate the memory at runtime, so they are modifyable. String litterals are not stored on the stack or heap, instead, they are stored in read only memory, so they cannot be modified.