为什么strtok()在C程序中不能正常工作?

6ju8rftf  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(129)

我正在尝试开发一个小的控制台程序,它可以将一个字符串分解为单独的单词(即:tokens).程序的大部分工作,但我有一个问题与strtok()函数.我已经查看了How does strtok() split the string into tokens in 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()函数似乎没有在String中沿着(源)输入字符串移动。当程序运行时,它会产生以下输出

./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()成功地读取了第一个token(根据代码块Watches面板,并以“\000”终止它),但没有读取inString中的后续token。由于我使用strtok()的方式与上面链接的页面上的代码中显示的方式非常相似,有人能解释一下我没有理解的是什么吗?

q1qsirdb

q1qsirdb1#

在这个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指向的字符串中的一个字符分隔。**序列中的第一个调用有一个非空的第一个参数;序列中的后续调用的第一个参数为空。**s2指向的分隔符字符串可能会因调用而异。
请注意,函数返回传递的字符串中的单词数会更好,例如

unsigned int makeWordList(char inString[], unsigned int wordCount, char * wordList[])    // Separate out words.
{
   unsigned int index = 0;

   //...

   return index; 
}

请记住,函数strtok在多线程环境中是不安全的,因为它使用静态变量。使用替代函数strtok_s更安全。

t98cgbkg

t98cgbkg2#

问题是,在循环的每次迭代中,您都使用相同的字符串指针(inString)调用strtok()。这意味着strtok()只会从第一个token的末尾开始查找下一个token。在本例中,第一个标记是“three”,因此strtok()只会查找从“three”结尾开始的下一个标记。这就是为什么你的程序输出是“333”。

// 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()
}

相关问题