Parsing strings in C using strtok

I have this little source code made to parse a string like string variable I need to use in another project

 #include <stdio.h> #include <stdlib.h> #include <string.h> int main (void) { char string[] = "C-AC-2C-3C-BOB"; char* s; char* hand[3]; char* usr; s = (char*) calloc(1, sizeof(char)); hand[1] = (char*) calloc(3, sizeof(char)); hand[2] = (char*) calloc(3, sizeof(char)); hand[3] = (char*) calloc(3, sizeof(char)); usr = (char*) calloc(21, sizeof(char)); s = strtok (string,"-"); hand[1] = strtok (NULL, "-"); hand[2] = strtok (NULL, "-"); hand[3] = strtok (NULL, "-"); usr = strtok (NULL, "\0"); printf("%s:%s:%s:%s:%s\n", s, hand[1], hand[2], hand[3], usr); return 0; } 

The problem is that I got these 3C:AC:2C:3C:BOB as the result of printf instead of C:AC:2C:3C:BOB .

------- EDIT -----

Code without memory leaks. The problem remains

 #include <stdio.h> #include <stdlib.h> #include <string.h> int main (void) { char string[] = "C-AC-2C-3C-BOB"; char* s; char* hand[3]; char* usr; s = strtok (string,"-"); hand[1] = strtok (NULL, "-"); hand[2] = strtok (NULL, "-"); hand[3] = strtok (NULL, "-"); usr = strtok (NULL, "\0"); printf("%s:%s:%s:%s:%s\n", s, hand[1], hand[2], hand[3], usr); return 0; } 
+4
source share
5 answers

You declare the hand array as having three entries, then index it using indices 1 through 3 . But arrays in C have indices from 0 to size-1 (for example, 2 in your case).

So you write / read to / from outside the array, which leads to undefined behavior.

Change the indices of your array to 0 by 2 , and it should work fine.

+4
source

In code, you have an index problem that causes Undefined behavior at runtime:

 hand[3] = strtok (NULL, "-"); ^ printf("%s:%s:%s:%s:%s\n", s, hand[1], hand[2], hand[3], usr); ^ wrong index value 

Remember that the index value in the array starts at 0 according to the declaration of char* hand[3]; index values ​​can be from 0 to 2

+4
source
 #include <stdio.h> #include <stdlib.h> #include <string.h> int main (void) { char string[] = "C-AC-2C-3C-BOB"; char* s; char* hand[3]; char* usr; s = strtok (string,"-"); hand[0] = strtok (NULL, "-"); hand[1] = strtok (NULL, "-"); hand[2] = strtok (NULL, "-"); usr = strtok (NULL, "\0"); printf("%s:%s:%s:%s:%s\n", s, hand[0], hand[1], hand[2], usr); return 0; } 

You do not need to calloc your pointers, since strtok() will return a valid memory address (actually strtok() changes the string and replaces the delimiter with a char zero). Another issue is array indexes: in C, an index starts at zero. The first hand element is hand[0] , and the last is hand[2] .

+4
source

Here is the package for your program:

 +-----------------------+ | ... | |0x***00 hand[0] | | | |0x***04 hand[1] | | | |0x***08 hand[2] | | | |0x***0C hand[3] | <---hander[1] pointer this address | |______ hand[3] end here 

So, hand [3] uses the address covering * hand [1], this is 3C come

+1
source

First, you must annotate these lines to avoid memory leaks:

 s = (char*) calloc(1, sizeof(char)); hand[1] = (char*) calloc(3, sizeof(char)); hand[2] = (char*) calloc(3, sizeof(char)); hand[3] = (char*) calloc(3, sizeof(char)); usr = (char*) calloc(21, sizeof(char)); 

Then, after changing the code, I create and run the result on Windows and Linux, and I did not get an unexpected print result. A.

0
source

Source: https://habr.com/ru/post/1496526/


All Articles