String parsing in C using strtok

半腔热情 提交于 2019-12-23 14:54:10

问题


I've got this little source code, made for testing the parsing of a string similar to variable string I need to use in other 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 result of printf instead of C:AC:2C:3C:BOB.

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

Code without memory leaks. 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;
}

回答1:


You declare an array hand as having three entries, then you index it using indexes 1 through 3. But arrays in C have indexes from 0 to size-1 (e.g. 2 in your case).

So you write/read to/from out of bounds of the array, leading to undefined behavior.

Change the indexes of your array to 0 through 2 and it should work fine.




回答2:


In your code you have out-of 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 index value in array starts with 0 according to declaration char* hand[3]; index values can be 0 to 2




回答3:


#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 don't need to calloc your pointers, since strtok() will return a valid memory address (actually strtok() modifies the string and replace the separator by an null char). The other problem is the indexes of the array: in C, an index starts at 0. The first element of hand is hand[0] and the last one is hand[2].




回答4:


Here is the stack of you 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 the hand[3] use the address the cover the *hand[1] , this is the 3C come




回答5:


Firstly, you should annotation 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 change the code, I build and run the result in Windows and Linux, neither got your unexpected print result.



来源:https://stackoverflow.com/questions/18183633/string-parsing-in-c-using-strtok

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!