Reputation: 67
So, how it works? I've the following block of code;
for (i = 0; i < N; ++i){
array[i] = malloc(M * sizeof(char));
fgets(buffer, M-1, fp);
array[i] = strtok(buffer, "\n");
}
If I execute printf("%s", array[i]);
inside the for
the strtok()
works as I expected, but if I do
for (i = 0; i < N; ++i)
printf("%s", array[i]);
outside the previous for
, I obtain a loop of N
array[0]
.
Upvotes: 2
Views: 1278
Reputation: 134286
What is wrong with the function
strtok()
?
Nothing, function works as expected. The way it is used here, creates the problem.
Note: You have already received the answer from Mr. dasblinkenlight, however, just to elaborate another missing point, adding this answer.
The problems in your code are
Point 1. As already mentioned, strtok()
does not return a value that is persistent among successive calls. You've to copy the value of the returned token in each call, otherwise, you'll not get the expected value. For that, either you have to (after a sanity check of NULL token)
1.1. Take a pointer, allocate memory (using malloc()
or family) and copy the token content using strcpy()
1.2. use (non-standard) strdup()
to directly copy the token to array[i]
. No need of allocating memory separately.
FWIW, for both the cases, one you're done with the array[i]
, you need to free()
it.
Point 2: By allocating memory to array[i]
using malloc()
array[i] = malloc(M * sizeof(char));
and then assigning another pointer to it
array[i] = //some pointer...
you're overwriting the previously allocated pointer, thereby facing memory leak. Avoid this design and follow either of the above ways to get your code to work properly.
That said,
sizeof(char)
is guranteed to produce 1
according to C
standard. Multiplication by sizeof(char)
is likely to be avoided.fgets()
to ensure a successful read.Upvotes: 2
Reputation: 726489
The problem with strtok
is that the token it returns you becomes invalid as soon as you make the next call of strtok
. You could either copy it into a separate string, or use it right away, and discard, but you must use it before calling strtok
again.
for (i = 0; i < N; ++i){
array[i] = malloc(M * sizeof(char));
fgets(buffer, M-1, fp);
char *tok = strtok(buffer, "\n");
array[i] = malloc(strlen(tok)+1);
strcpy(array[i], tok);
}
Of course now you need to call free
on all elements of your array[]
after you are done with them.
Note that strtok
is not re-entrant, which severely limits its use. A better choice is strtok_r
, which is a re-entrant version of the same function.
Upvotes: 1