strtok在呼叫中的问题

我有一个像这样使用strtok的函数

void f1(char *name) { ... char *tmp; tmp = strtok(names, " ,"); while(tmp) { ... tmp = strtok(NULL, " ,"); } ... } 

我有一个电话f1(“abc,def”);

问题是,在第一次调用f1获得abc时,def和第二次调用只获得abc

我很困惑..为什么会这样?

strtok()通过用0覆盖分隔符来修改其输入字符串; 所以,假设您的代码看起来像这样:

 char parm[] = "abc,def"; f1(parm); f1(parm); 

在第一次调用f1之后,’,’字符被0覆盖,这是一个字符串终止符,因此第二个调用只将“abc”视为字符串。

请注意,因为strtok()修改了它的输入,所以您不希望将字符串文字作为参数传递给它; 尝试修改字符串文字的内容会调用未定义的行为。

安全的做法是在f1中创建一个本地字符串并将名称的内容复制到它,然后将该本地字符串传递给strtok() 。 以下内容适用于C99:

 void f1(char *name) { size_t len = strlen(name); char localstr[len+1]; char *tmp; strcpy(localstr, name); tmp = strtok(localstr, " ,"); while(tmp) { ... tmp = strtok(NULL, " ,"); } } 

你说:

我有一个电话f1(“abc,def”);

该调用是非法的 – strtok修改其第一个参数,并且不允许修改字符串文字。 你得到的是未定义的行为 – 任何事情都可能发生。 你要:

 char a[] = "abc,def"; f1( a ); 

你真的传入一个字符串文字吗?

 f1("abc,def"); 

将指向字符串文字的指针传递给f1() strtok() f1() – 因为strtok()修改了字符串,并且不能修改字符串文字,所以你会得到未定义的行为(尽管我会期待崩溃)或错误而非意外结果)。

strtok在返回的每个标记后放置一个null终止符。 这意味着它会破坏原始字符串:在调用它之后,您的字符串将在第一个令牌后终止,从而导致您看到的行为。

要保持原始字符串不变,您需要在调用strtok之前复制它。