提问人:Stuart 提问时间:8/29/2023 最后编辑:Vlad from MoscowStuart 更新时间:8/29/2023 访问量:86
为什么 strtok() 在我的 C 程序中无法正常工作?
why is strtok() not working properly in my C program?
问:
我正在尝试开发一个小型控制台程序,该程序将字符串吐出为单独的单词(即标记)。大部分程序都在工作,但我的 strtok() 函数有问题。我已经查看了 strtok() 如何在 C 语言中将字符串拆分为标记中显示的代码,并在某种程度上基于我自己的代码。我的问题出在我的makeWordList()函数上,如下所示。
// Assumes a multi-word string was entered.
void makeWordList(char inString[], unsigned int wordCount, char * wordList[]) // Separate out words.
{
unsigned int index = 0;
const char * delimiter = " ";
char * word;
word = strtok(inString, delimiter); // Get first word.
while ((word != NULL) && (index < wordCount))
{
wordList[index++] = word; // Add word to list.
word = strtok(inString, delimiter); // Get next word.
} // end while()
}
就我而言,strtok() 函数似乎不会沿着(源)输入字符串 inString 移动。当程序运行时,它会生成以下输出
./ex8_4
Enter string to be processed:
three word string
You entered |three word string|
There are 3 words in the string.
There are 15 letters in the string.
The word list is as follows.
three
three
three
从上面显示的输出中可以很容易地看到 strtok() 成功读取了第一个令牌(并根据代码块监视面板以“\000”终止它),但没有读取 inString 中的后续令牌。 由于我使用 strtok() 的方式与上面链接的页面上的代码中显示的方式非常相似,有人可以解释一下我无法理解的内容吗?
答:
问题在于,在循环的每次迭代中,您都使用相同的字符串指针 (inString) 调用 strtok()。这意味着 strtok() 将只从第一个令牌的末尾开始查找下一个令牌。在您的例子中,第一个标记是“three”,因此 strtok() 只会找到从“three”末尾开始的下一个标记。这就是为什么你的程序的输出是“三三三”。
// Assumes a multi-word string was entered.
void makeWordList(char inString[], unsigned int wordCount, char * wordList[]) // Separate out words.
{
unsigned int index = 0;
const char * delimiter = " ";
char * word;
word = strtok(inString, delimiter); // Get first word.
while ((word != NULL) && (index < wordCount))
{
wordList[index++] = word; // Add word to list.
// Get next word.
word = strtok(NULL, delimiter);
} // end while()
}
在此 while 循环中
while ((word != NULL) && (index < wordCount))
{
wordList[index++] = word; // Add word to list.
word = strtok(inString, delimiter); // Get next word.
}
更改此语句
word = strtok(inString, delimiter); // Get next word.
自
word = strtok(NULL, delimiter); // Get next word.
否则,该函数会尝试从头开始重新拆分字符串。strtok
来自 C 标准(7.23.5.8 strtok 函数)
2 对 strtok 函数的一系列调用中断了指向的字符串 通过 s1 进入一系列令牌,每个令牌都由 S2 指向的字符串中的字符。第一个调用 sequence 有一个非 null 的第一个参数;后续调用 sequence 的第一个参数为 null。指向的分隔符字符串 通过 S2 可能与呼叫不同。
请注意,当函数返回传递的字符串中的字数时会更好,例如
unsigned int makeWordList(char inString[], unsigned int wordCount, char * wordList[]) // Separate out words.
{
unsigned int index = 0;
//...
return index;
}
请记住,该函数在多线程环境中是不安全的,因为它使用静态变量。使用替代功能更安全。strtok
strtok_s
评论
makeWordList
main
NULL
wordList
strtok()
word = strtok(inString, delimiter); // Get next word.
这不是工作方式。您必须传递除第一个调用之外的所有调用。strtok
NULL