0
votes

Hey guys I'm getting a seg fault with strtok, just need a little bit of help!

char s[1024];
char *token[2];
while(fgets(s, sizeof(s), fp) != NULL) // Read line from file fp until end
{
    token[0] = strtok(s, "\t\n");
    token[1] = strtok(NULL, "\t\n");
    token[2] = strtok(NULL, "\t\n");
    printf("%d:%s:%d", atoi(token[0]), token[1], atoi(token[2]));
}

But I get a seg fault after the first passover of the loop. The input file reads something like this:

102910319    code    mark
.
.
.
104981851    code    mark

But the while loop only prints the first line correctly and seg faults on the second line.

Any ideas why?

Thanks.

3
my first guess: you declared token[2] but you access 3 elementsJack
also possible, after you fix the array declaration you may have data problems: - the white characters between columns are other than \t.jim mcnamara
Fixed but still get the seg fault! @jimmcnamara Nope, they are all \t (tabs).Travv92
For token[1] and token[2], do we require \t\n or only \t is sufficient as the delimiter?Ganesh
You code will segfault on non \t whitespace characters. Because you will have NULL returned early. token[2] could be NULL for example. Check the output of the command: od -c inputfile | more.jim mcnamara

3 Answers

2
votes

Array indexing problem.

You should declare the array of pointers as follows,

char *token[3];
0
votes

As Jack said, token is declared to store two char *s: token[0] and token[1]. token[2] is out of range. The solution to this is to change your declaration of token: char *token[3];.

Additionally, it could be that you've provided less than three "words" of input somewhere, in which the %s will tell printf to print a string pointed to by a null pointer, or the second atoi call will attempt to dereference a null pointer. The solution is to check token[1] before passing it to printf, and token[2] before passing it to atoi: printf("%d:%s:%d", atoi(token[0]), token[1] ? token[1] : "null", token[2] ? atoi(token[2]) : 0);

Alternatively, it looks like scanf might be more suitable for this:

int x, y;
char str[1024];
while (scanf("%d %1023s %d", &x, str, &y) == 3) {
    printf("%d:%s:%d\n", x, str, y);
}
0
votes

You do it

char *token[2]

it can only allocate two char pointer not three.