efoekfoe - 1 year ago 82
C Question

# Unexpected Behaviour when using strtok

So I'm given a string as such:

``````Hello6World66ABC
``````

Where I'm told to replace single instances of the character '6' to be two asteric characters
`"**"`

And multiple instances of 6's to be two of these characters
`"^^"`
(Any combinations of the number 6 in a row would qualify.

I'm attempting to do this by passing through each character in a
`char *`
,then if I find the 6 character, I check if the next character is a 6, if not we have the first case, otherwise we have the second case (Multiple 6's).

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

int main(void) {
char * str;
int i;
str = malloc(17);

strcpy(str,"Hello6World66ABC");

for(i=0; i < strlen(str); i++) {
if(str[i] == '6') {
if(str[i+1] != '6') {
char * token = strtok(str,"6");
strcpy(str,token);
strcat(str,"**");
printf("String is now %s\n",str);

token = strtok(NULL,""); /*get the rest of the string*/ /* should be World66ABC */
printf("Rest of the string is %s\n",token);
str = (char *) realloc(str,strlen(str) + strlen(token) + 1);
strcat(str,token);
printf("String is now %s\n",str);
/*    should be Hello**World66ABC    */
}
else {
/*if the next characters are also (multiple ones in a row)  6's, replace it with two ^^ characters*/
char * token = strtok(str,"6");
token = strtok(NULL,"6");
printf("TOKEN IS %s\n",token);

strcpy(str,token);
strcat(str,"^^");

token = strtok(NULL,""); /*get the rest of the string*/ /* should be World66ABC */
printf("Rest of the string is %s\n",token);
str = (char *) realloc(str,strlen(str) + strlen(token) + 1);
strcat(str,token);
printf("String is now %s\n",str);

}
}
}

free(str);
return 0;
}
``````

By the string given, My expected final string should be:

``````Hello**World^^ABC
``````

However, my strtok calls don't work the way I intended.

In the second if statement, where I check
`if (str[i+1] != '6')`
, I'm checking if there is only a single 6, there is.

Then I call strtok and print everything before it:
it prints:
`Hello**`

Which is correct
I strcat the new characters on to it which works, however, on my second strtok call, to get the rest of the string, it just doesn't work.

``````"Rest of the string is *"
``````

So clearly it's not getting the rest of the string, even though I set the delimiter to be an empty string.

I tried to change the delimiter to be other characters, but each result in the same output. I'm also reallocating because the string gets longer, in the first case. Also the else statement seems to never run, even though I clearly have a case where there are multiple 6's.

I'm not sure where I've gone wrong here, any ideas?

This is untested, but it shows the general idea.

``````strcpy(str,"Hello6World66ABC");

// New string will be at most 2x as long
char *new_str = calloc(strlen(str) * 2 + 1, 1);
int new_str_index = 0;

for (int i = 0; 0 != str[i]; i++) {
// Check for 6
if ('6' == str[i]) {
// Check for 2nd 6
if ('6' == str[i+1]) {
new_str[new_str_index++] = '^';
new_str[new_str_index++] = '^';
// Consume remaining 6s - double check this for off-by-one
while ('6' == str[i+1]) i += 1;
}
else {