Strtok_r 返回 NULL

Posted

技术标签:

【中文标题】Strtok_r 返回 NULL【英文标题】:Strtok_r returning NULL 【发布时间】:2019-06-19 14:47:47 【问题描述】:

我正在尝试对从文件中提取的字符串进行标记。 strtok_r 在第一个子字符串上正常工作,然后返回 null(以及分段错误,因为我尝试将 strndup 转换为另一个 var)

char buffer[500];
char * c;
char * c1;
char * c2;
//....
while(fgets(buffer, sizeof(buffer), f) != NULL)
    c2 = buffer;
    printf("%s\n", buffer);
    c = strtok(c2, ":");
    for(int i = 0; i < 4; i++)
        c = strtok(NULL, ":");
        printf("%s\n", c);
    
    if(strcmp(c, argp->origen) == 0)
        c = strtok(NULL, ":");
        printf("%s\n", c);
        if(strcmp(c, argp->destino) == 0)
            nodo = malloc(sizeof(lista_vuelo));
            c2 = buffer;

            c = strtok_r(c2, ":", &c1); 
            nodo->IdReg = atoi(c);
            printf("\n%d test\n", nodo->IdReg); //Works until here

            c = strtok_r(NULL, ":", &c1);
            printf("\n%s\n", c); //Prints null and then segmentation fault

            nodo->Idvuelo = strndup(c, strlen(c));
            printf("\n%s\n", nodo->Idvuelo);
//....

文件输入:

3:IBE3674:02-04-2019:19-45:马德里:柏林:巴拉哈斯:泰格尔:伊比利亚:210:35:6:T4:60:N

输出:

3 次测试 -> 预期输出

(null)
Violación de segmento (`core' generado) -> Segmentation fault, (null) should be IBE3674

【问题讨论】:

你的意见是什么? @Yastanub 从文件中读取,输入为 3:IBE3674:02-04-2019:19-45:Madrid:Berlin:Barajas:Tegel:IBERIA:210:35:6:T4 :60:N // 将其添加到主帖 你期望 strtok 返回什么?为什么? 指向下一个标记的指针,以便我可以将其添加到结构中包含的字符指针中 好吧,如果strtok 返回NULL 之后你的程序崩溃了,你应该考虑在使用NULL 指针之前检查返回值。如果您已经将NULL 传递给printf,则会调用未定义的行为。之后您仍然忽略NULL 并将指针输入strlenstrndup。如果您将 NULL 输入到大量意想不到的函数中,那么崩溃也就不足为奇了 【参考方案1】:

strtok 不只是修改它传递的指针,而是实际修改字符串本身。它用null 字符替换每个找到的分隔符。

如果你有字符串test:strtok:for:me,然后在你有test\0strtok:for:me之后调用strtok

因此,当您迭代提供前几个令牌时,每个 : 都将替换为 \0。如果您现在将指针 c2 重置为字符串的开头并再次调用 strtok,strtok 会在找到分隔符之前找到 null 字符,并假定字符串在找到分隔符之前结束并返回 NULL

【讨论】:

所以,我应该将缓冲区的副本复制到 c2 中,而不仅仅是分配指针,对吗?是的,它成功了,非常感谢你 @Opresor 这将是一种可能性,但随后您在内存中有 2 次相同的字符串(几乎至少)。您还可以将第一个标记保存到一个数组中,然后再使用它们。另请注意,strtok 不会创建新字符串,而只会将分隔符替换为 0,然后返回指向标记开头的指针。因此,您的实际字符串并没有真正拆分,而只是分段。如果删除初始字符串,所有标记都将失效。

以上是关于Strtok_r 返回 NULL的主要内容,如果未能解决你的问题,请参考以下文章

关于函数strtok和strtok_r的使用要点和实现原理

关于函数strtok和strtok_r的使用要点和实现原理

C语言字符串相关函数使用示例 strtok_r strstr strtok atoi

为啥 WCF/JSON 不为 null 返回值返回“null”?

返回一个空任务还是返回null更好? C#

places.getLatLng() 返回 null 虽然 places.getName() 没有返回 null