如何使用strtok剪切大小不同的字符串?

时间:2019-03-27 19:21:38

标签: c string strtok

因此,我对C还是一个新手,我得到了像这样的字符串a:name:number:number:number:number:name:name,并且我正在使用strtok来获取所有没有":"的名称和数字。问题是,字符串的大小可以变化,并且最多可以有两个名称(总是在结尾),例如:a:name:number:number:number:number:name:name:namea:name:number:number:number:number:name:name:name:name

现在,我正在使用struct和strcpy来获取结构中的每个名称,但是由于最后名称的变化量很大,所以当结尾处少于4个名称时,我会遇到Segmentation Faults。名称的最大数量(最小为1),我认为这是因为在字符串结尾之后我继续执行strtok。

这是我的代码:

char *token;
structname a;
token = strtok(c,":"); //c is the input string
strcpy(a.name1,strtok(NULL,":"));
a.number1 = atoi(strtok(NULL,":"));
a.number2 = atoi(strtok(NULL,":"));
a.number3 = atoi(strtok(NULL,":"));
a.number4 = atoi(strtok(NULL,":"));
strcpy(a.name2,strtok(NULL,":"));
strcpy(a.name3,strtok(NULL,":"));
strcpy(a.name4,strtok(NULL,":"));
strcpy(a.name5,strtok(NULL,":"));

所以,我猜测错误的发生是因为即使在没有4个中间名的情况下,即使字符串结束后,它仍会继续执行strtok吗? 我想知道如何处理,例如,在末尾有两个名称的情况下,只需将a.name4a.name5改为"\0"或不从这些字符串中获取任何内容。 感谢您的时间和帮助!

2 个答案:

答案 0 :(得分:1)

通常,strtok在循环中使用。例如:

char *token = strtok(input_string, ".");
while(token != NULL) {
    //do code
    token = strtok(NULL, ".");
}

这样,当第一次失败的解析发生时,循环结束。任何时候使用strtok时,都应在输入字符串的末尾继续返回NULL,这样就不会造成问题,但可能是这样。

我认为最可能的问题是在strcpy中使用strtok的方式。 strcpy可能失败,因为源字符串为NULL。如果您不想使用循环,该怎么办

token = strtok(NULL, ":");
strcpy(a.name2, token);

这样,在尝试复制之前,请确保它不是NULL指针。 strcpy适用于空字符串(“”),但不适用于NULL指针。

您可能要检查的另一件事是为目标字符串(a.name2等)分配了足够的空间。如果没有,这也会导致段错误。

答案 1 :(得分:1)

如果没有更多标记,则

strotok()返回NULL。因此,您应该检查返回值,例如:

if( (token = strtok(c,":")) != NULL ) 
    strcpy(a.name1,token);
else
   // token is NULL, there is no more tokens, end of string reached
   // you can return or do something else