4

I am trying to use strtok() to parse a string deliminated by spaces. From what I can tell, I am using it correctly, but it won't run on ideone.com. Is there anything wrong with the following code? I just get Runtime error time: 0 memory: 2288 signal:11

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

static void test(char *command)
{
    char* output = strtok(command, " ");
    printf("%s\n", output);
}

int main(void) {

    test("set_rate 200");

    return 0;
}

Here it is on ideone.com if you want to try it.

boltup_im_coding
  • 6,345
  • 6
  • 40
  • 52
  • Did you try it on your own computer? – Cole Tobin Oct 08 '13 at 04:44
  • I can't try it on my computer in my current development environment. – boltup_im_coding Oct 08 '13 at 04:47
  • Destroying your input in order to produce output is really bad function design. I recommend never using strtok. There are plenty of [alternative examples out there](http://pjd-notes.blogspot.com/2011/09/alternative-to-strtok3-in-c.html). – msw Oct 08 '13 at 04:58

4 Answers4

4

Always consult the man pages first.

strtok(3) says:

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.

Community
  • 1
  • 1
Jonathon Reinhart
  • 132,704
  • 33
  • 254
  • 328
3

As strtok modifies the string, it requires that the string is not in read-only memory. So when you pass a string literal to your test function, it crashes.

This is better:

char s[] = "set_rate 200";
test(s);
goji
  • 6,911
  • 3
  • 42
  • 59
  • 1
    It may help to explain that in your modified code, the string is on the (read-write) stack of `main`, instead of a read-only section. – Jonathon Reinhart Oct 08 '13 at 04:51
3

strtok will modify the string passed as the first parameter, so you can't pass a string literal, change your main like this:

int main(void) {  
    char str[] = "set_rate 200";
    test(str);
    return 0;
}

str here is an char array, but not a string literal.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
  • 1
    I appreciate the explanation. I'm still fairly new to C. I thought that `char* str` and 'char[] str' were equivalent. Isn't a `char[]` just a pointer to a `char`? How are these different? – boltup_im_coding Oct 08 '13 at 04:48
  • 1
    @unexpected62 By actually declaring the variable you are allocating a ram variable. By directly placing the string in the parameter it is compiled into something stored only ROM when using most C compilers. – NickHalden Oct 08 '13 at 04:52
  • @unexpected62 char s[] = "string"; creates a mutable string where s is a char array allocated with length of string + 1 bytes. char *s = "string", creates a string constant which is pointed to by s. You are free to modify the first s with [], but you cannot do so for the char *s. Hope that helps. – fkl Oct 08 '13 at 04:56
2

When you pass hard coded string that was stored in read-only memory.

strtok() does not work with string which is read-only memory.

You need to use string variable rather than string literal .

you can first store string in some variable and then you can pass it to the function.

char[]="set_rate 200";
test(str);

See example:

 char *str = malloc(20);
    char *tok = NULL;
    int len = 0;

    strcpy(str, "This is a string");
    len = strlen(str);

    printf("string before strtok(): %s\n", str);
    tok = strtok(str, " ");
    while (tok) {
        printf("Token: %s\n", tok);
        tok = strtok(NULL, " ");
    }

Edit

From @Yu Hao comment i am adding this

char *str = "set_rate 200"; 
test(str); // This won't work. here str is pointer to the string literal. 
Gangadhar
  • 10,248
  • 3
  • 31
  • 50
  • 1
    Your first attempt is **wrong**. In `char *str = "set_rate 200";`, `str` is still a pointer to a string literal. The problem remains. The code in the comment is correct, and they are **not** the same. – Yu Hao Oct 08 '13 at 04:58
  • Yes those both are not same.`*str` is pointer to string and `str[]` is char array.can you clarify a bit more here. why it is not working with `*str` – Gangadhar Oct 08 '13 at 05:13
  • 1
    See [What is the difference between `char s[]` and `char *s` in C](http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c) – Yu Hao Oct 08 '13 at 05:14
  • Thanks. first lines of accepted answer are more than enough explanation. – Gangadhar Oct 08 '13 at 05:16