我正在使用库中的strtok(...),它的表现良好,直到终止条件出现时,它会导致分段错误和程序崩溃。该API声称,当没有更多标记可以找到时,strtok(...)将输出NULL,这意味着,我认为,您必须捕获此NULL以终止使用strtok(...)运行的任何循环。我需要做什么来捕获这个NULL以防止我的程序崩溃?我想象中,NULL被允许用作终止条件。
我为您准备了一个SSCCE,以观察此行为。我需要strtok(...)在我正在编写的大型软件中工作,但我遇到了完全相同的分段行为。命令行输出如下所示(是的,我知道您要使用<...>来包含库,但我无法使此帖子显示代码库)。我正在使用Windows 8操作系统上的gcc版本4.5.3,下面展示了两种不同的尝试在循环中捕获NULL的方式。
我为您准备了一个SSCCE,以观察此行为。我需要strtok(...)在我正在编写的大型软件中工作,但我遇到了完全相同的分段行为。命令行输出如下所示(是的,我知道您要使用<...>来包含库,但我无法使此帖子显示代码库)。我正在使用Windows 8操作系统上的gcc版本4.5.3,下面展示了两种不同的尝试在循环中捕获NULL的方式。
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
main(){
char* from = "12.34.56.78";
char * ch = ".";
char * token = strtok(from, ch);
printf("%s\n",token);
while(token != NULL){
token = strtok(NULL, ch);
printf("%s\n", token);
}
printf("Broke out of loop!");
while(strcmp(token, 0) != 0){
printf("%s\n",token);
token = strtok(NULL, ch);
}
}
############ 输出: ############ $ ./test 12 34 56 78 段错误 (核心已转储)
strtok
发生段错误时,这并不意外。它只应与gets
结合使用(也就是说,永远不要使用gets
!) - William Pursellstrcmp(NULL,0)
<- 炸了! - Aniket Ingegets
。strtok
不是那么糟糕,但我通常发现它并不必要,因为最好通过 lex/bison/yacc 进行标记化。 - William Pursell