6

for some reason i get an exception at the first use of strtok() what i am trying to accomplish is a function that simply checks if a substring repeats itself inside a string. but so far i havent gotten strtok to work

int CheckDoubleInput(char* input){
char* word = NULL;
char cutBy[] = ",_";

word = strtok(input, cutBy);  <--- **error line**

/* walk through other tokens */
while (word != NULL)
{
    printf(" %s\n", word);
    word = strtok(NULL, cutBy);
}
return 1;
}

and the main calling the function:

CheckDoubleInput("asdlakm,_asdasd,_sdasd,asdas_sas");

screenshot of the error im getting

Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
Felix Kreuk
  • 193
  • 1
  • 9
  • 4
    `input` should point to a modifiable array, don't call your function as `CheckDoubleInput("Hello,_word");` – Grijesh Chauhan Dec 28 '13 at 09:44
  • Read [strtok causing segfault but not when step through code](http://stackoverflow.com/questions/17551665/strtok-causing-segfault-but-not-when-step-through-code/17551779#17551779) – Grijesh Chauhan Dec 28 '13 at 09:47
  • ok also tried: `char* string = "asdasd,_asdasd"; CheckDoubleInput(string);` still doesnt work – Felix Kreuk Dec 28 '13 at 09:49
  • 1
    Try as `char string[] = "asdlakm,_asdasd,_sdasd,asdas_sas";` Read the answer I linked with your question. – Grijesh Chauhan Dec 28 '13 at 09:50
  • Flelix You should also learn [`Difference between `char *str` and `char str[]` and how both stores in memory?`](http://stackoverflow.com/questions/15177420/what-does-sizeofarray-return/15177499#15177499) – Grijesh Chauhan Dec 28 '13 at 09:52
  • ok, so how could i use strtok() on a string im getting as an argument in a function? – Felix Kreuk Dec 28 '13 at 09:52
  • Felix:See do like `char string[] = "asdlakm,_asdasd,_sdasd,asdas_sas"; CheckDoubleInput(string);"` Read the answer I have linked exactly answer your question. – Grijesh Chauhan Dec 28 '13 at 09:54
  • Grijesh Chauhan, thanks, it works with [], but still...i need it to get char* as an argument. :\ – Felix Kreuk Dec 28 '13 at 09:56
  • Fleix You don't need to change function arguments type. The problem **was** you were passing a `constant string literal` that can't be modified. So I linked the another question to learn differences between `char*` and `char[]` – Grijesh Chauhan Dec 28 '13 at 09:59
  • thanks alot! i will read it now – Felix Kreuk Dec 28 '13 at 10:02
  • You can start the process from the copy inside the function, to change the check of a type that does not break the string. – BLUEPIXY Dec 28 '13 at 10:07
  • Please copy the text from the screenshot into the body of the question. You can use "Ctrl-C" to copy the text from most dialog boxes in Windows. – Ganesh Sittampalam Dec 28 '13 at 10:42

3 Answers3

2

CheckDoubleInput() is ok. Look at this. Hope you will understand

int main(){
    char a[100] = "asdlakm,_asdasd,_sdasd,asdas_sas";
    // This will lead to segmentation fault.
    CheckDoubleInput("asdlakm,_asdasd,_sdasd,asdas_sas");
    // This works ok.
    CheckDoubleInput(a);
    return 0;
}
taufique
  • 2,701
  • 1
  • 26
  • 40
1

The strtok function modify its first input (the parsed string), so you can't pass a pointer to a constant string. In your code, you are passing a pointer to a string literal of char[N] type (ie. a compilation constant string) and hence trying to modify a constant string literal which is undefined behaviour. You'll have to copy the string in a temporary buffer before.

char* copy = strdup("asdlakm,_asdasd,_sdasd,asdas_sas");
int result = CheckDoubleInput(copy);
free(copy);

Here is what the man page for strtok says:

Bugs

Be cautious when using these functions. If you do use them, note that:

  • These functions modify their first argument.
  • These functions cannot be used on constant strings.
  • The identity of the delimiting byte is lost.
  • The strtok() function uses a static buffer while parsing, so it's not thread safe. Use strtok_r() if this matters to you.
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
Sylvain Defresne
  • 42,429
  • 12
  • 75
  • 85
  • thank, but i cant initialize `char* copy = strcpy("asdlakm,_asdasd,_sdasd,asdas_sas");` like that, i need it to get the *char sent as argument – Felix Kreuk Dec 28 '13 at 10:11
  • @FelixKreuk Actually it should be [`strdup()`](http://stackoverflow.com/questions/252782/strdup-what-does-it-do-in-c) updated answer. read again – Grijesh Chauhan Dec 28 '13 at 10:46
0

Either input is somehow bad. Try printing it before calling strtok OR you're using strtok on multiple threads with GCC compiler. Some compilers have a thread safe version called 'strtok_r'. Visual Studio have fixed the original function to be thread safe.

Your modified answer shows that you're passing a string literal which is read only.

egur
  • 7,830
  • 2
  • 27
  • 47
  • you can see that the value of input is ok in the picture i attached – Felix Kreuk Dec 28 '13 at 09:57
  • It's not OK, passing a string literal is dangerous. pass copy of it as strtok will modify it. The memory where the string literal are stored is read only. – egur Dec 28 '13 at 10:03