Search code examples
csplitc-stringsstrtokstrsep

C-string alternatives to strtok_r() and strsep() that don't modify the original string pointer?


I was taking a look at the 2 C-string functions, strtok_r() and strsep(), and noticed both functions modify the location of the original string passed in.

Are there any other C-string functions that don't modify the original string passed in?

In my application, the original string is dynamically allocated, so I wish to free the original string after the parsing is done.

An example with strtok_r()

int main(){
    char * str = strdup("Tutorial and example");
    char* token;
    char* rest = str;
    
    printf("%s\n", rest);
    while ((token = strtok_r(rest, " ", &rest)))
        printf("%s\n", token);
    printf("\n%s\n",str);
    return(0);
}

Output

Tutorial and example                                                                                                                                                        
Tutorial                                                                                                                                                                    
and                                                                                                                                                                         
example                                                                                                                                                                     
                                                                                                                                                                            
                                                                                                                                                                            
                                                                                                                                                                            
Tutorial                                                                                                                                                                          

In the very last line, I wish for str to point to the unmodified cstring "Tutorial and example".

A similar output would have occured with strsep() as well.

int main(){
    char * str = strdup("Tutorial and example");
    char* token;
    char* rest = str;

    printf("%s\n", rest); 
    while ((token = strsep(&rest, " ")))
        printf("%s\n", token);
    if (rest != NULL)
        printf("%s\n", rest);
        
    printf("%s\n", str); 
    return(0);
}

Thank you.


Solution

  • I think you are misunderstanding strtok_r. It does not change the location of the original string, moreover, it can not - the function can not change the value of the pointer passed into it and make this change visible to the calling code.

    What it can and will do is modifying the contents of the string itself, by replacing tokens with nul-terminators. So to answer your original question:

    In my application, the original string is dynamically allocated, so I wish to free the original string after the parsing is done.

    You do not have to do anything special. You can and should free original string after you are done with it.

    You are seeing a single word Tutorial printed simply because the next character was replaced with nul-terminator and printf stop there. If you are to inspect the string character by character, you will see that it otherwise have remained intact.