Reputation: 168
I need to separate string from file. String = "21:12:36 14:45:25 08:17:24" When i do strtok() and put all tokens to array everything works fine, but when I do strtok() second time, it messes everything. Example:
char *p = strtok (code, " ");
while (p != NULL){
dal[i++] = p;
p = strtok (NULL, " ");
}
Output:
dal[0] = 21:12:36
dal[1] = 14:45:25
dal[2] = 08:17:24
I do copy of dal array, and when I do strtok for second time i changes my original string(code) and my copy of dal even I pass dal array only to strtok(). I tried to send dal to LinkedList, but after second strtok even LinkedList is changed.
Declaration:
char *dal[20], *dalcopy[20];
//copying below
for(int k = 0; k<i; k++){
dalcopy[v] = dal[k];
v = v+1;
}
Example:
for (int j = 0; j<i; j++){
char *o = strtok(dal[j], ":");
while (o != NULL){
for(int h = 0; h<3; h++){
if(h == 0){vienas[b].Hour = atoi(o);}
if(h == 1){vienas[b].Min = atoi(o);}
if(h == 2){vienas[b].Sec = atoi(o);}
o = strtok (NULL, ":");
}
b = b+1;
}
LinkedList example:
char *p = strtok (code, " ");
while (p != NULL){
dal[i++] = p;
put(head, p); //puts each element to list end
p = strtok (NULL, " ");
}
printf("%s\n", show_by_index(&head, 0)); **Output == 21 after second strtok**
Output:
original string = 21
dal[0] = 21
dal[1] = 14
dal[2] = 08
dalcopy[0] = 21
etc...
Why this is happening?
Upvotes: 1
Views: 68
Reputation: 20244
The two main things you've fo keep in mind are:
strtok
is a destrutive function as said by @JohnColeman in the comments. This means that strtok
modifies the string (first argument) passed to it.strtok
gives you pointers that point to different parts of the string and you store them in the array dal
. Now, you create another similar array of pointers dalcopy
(assuming you fixed what @David told you) and make them point to the same parts of the string code
as dal
does.dal
and dalcopy
point to the same tokens of the string code
. So, any change you make to them will also affect code
as they point to it.
Before strtok
and everything:
+--------+--------+--------+--------+
| dal[0] | dal[1] | dal[2] | dal[3] | ... = dal
+--------+--------+--------+--------+
+------------------------------+
| "21:12:36 14:45:25 08:17:24" | = code
+------------------------------+
After strtok
and "copying":
+--------+--------+--------+--------+
| dal[0] | dal[1] | dal[2] | dal[3] | ... = dal
+--------+--------+--------+--------+
↓ ↓ ↓
+---------------------------------+
| "21:12:36\0014:45:25\008:17:24" | = code
+---------------------------------+
↑ ↑ ↑
| \ \----\
+------------+------------+------------+------------+
| dalcopy[0] | dalcopy[1] | dalcopy[2] | dalcopy[3] | ... = dalcopy
+------------+------------+------------+------------+
As you can see, you were not copying it, but merely creating an alias.
The solution would be to strdup
/malloc
+strcpy
the tokens.
Upvotes: 2
Reputation: 182769
char *dal[20], dalcopy[20];
//copying below
for(int k = 0; k<i; k++){
dalcopy[v] = dal[k];
v = v+1;
}
This can't be right. Since dalcopy
is an array of characters, dalcopy[v]
is a character. But dal[k]
is not a character (since dal
is an array of pointers to characters), so this assignment makes no sense at all.
Upvotes: 1