【问题标题】:How to correctly count words using strtok?如何使用 strtok 正确计算单词?
【发布时间】:2018-11-27 18:37:10
【问题描述】:
#include <stdio.h>
#include <string.h>

int main(void) {

  char tekst[10000], test=0;
  char* word;
  char word_copy[100][100];
  int i=0, lenght=0;

  printf("Type in your text: ");
  fgets(tekst, 10000, stdin);

  lenght=strlen(tekst)-1;
  if(lenght>1000)
  {
    lenght=1000;
  }

  word=strtok(tekst, " ,\".-");

  while( word != NULL)
    {
      word=strtok(NULL, " ,\".-");
      printf("%s ", word);
      i++;

    }

  printf("%d", i);

你好。我想要做的是仅使用 strtok 来计算单词。但是,如果我输入:“example”或-example-,我得到的答案是“2”而不是“1”。出于某种原因,当最后一个单词为 (null) 时,它仍然会触发循环,并且 i++ 可以工作......我对编程很陌生,所以我也希望能写下正确的代码。

【问题讨论】:

  • 对于初学者,不要尝试打印NULL。在打印之前测试是否为 NULL。
  • 并在 strtok 返回 NULL 时中断,因此您不算数。
  • 现在学习如何使用调试器找出程序中发生的事情还为时过早。
  • 即使word 为空,您也可以算数。使用while ((word = strtok(NULL, " ,\".-")) != NULL) { printf("%s ", word); i++; }
  • 实际上,我知道我应该在打印前使用 strcpy 或测试它,但我很困惑,需要一些快速信息,然后在复制时将其留在这里,哈哈。非常感谢你。我之前尝试过打破while,但是我在if中使用了“word”,这次我按照建议尝试了完整的“strtok(..)”,它奏效了!我真的很感谢你的帮助。祝你有美好的一天!

标签: c string strtok


【解决方案1】:

从 cmets 开始,这里还有另一种修复代码的方法:

...
char *text = tekst;
while((word = strtok(text, " ,\".-"))) {
    text = NULL;
    printf("%s ", word);
    i++;
}
...

【讨论】:

  • GCC 将在一个几乎没有挑衅的条件下警告分配(-Wall 等)。我会写while ((word = strtok(text, " ,\".-")) != NULL) 来避免该警告——在生成的代码中是免费的。
  • @JonathanLeffler 我很惊讶 gcc 5.4.0 没有发出该警告(使用 -Wall 和 -pedantic)。
  • 额外的括号是 GCC 的标志,表明您知道自己在做什么。 (Otoh,MSVC 无论如何都会抱怨。)
【解决方案2】:

您想删除fgets() 的尾随换行符,如Removing trailing newline character from fgets() input 中所述。

然后,我删除了您代码中未使用的内容,例如长度。

正如strtok()reference 中提到的示例,您首先获取令牌,然后再次调用该函数。使用这种方法,您无需担心将 NULL 计算为一个单词(您的代码就是这样做的)。

把所有东西放在一起,我们得到:

#include <stdio.h>
#include <string.h>

int main(void) {

  char tekst[10000];
  char* word;
  int i=0;

  printf("Type in your text: ");
  fgets(tekst, 10000, stdin);
  tekst[strcspn(tekst, "\n")] = 0;

  word=strtok(tekst, " ,\".-");

  while( word != NULL)
  {
      printf("%s ", word);
      word=strtok(NULL, " ,\".-");
      i++;

  }

  printf("%d", i);

  return 0;
}

输出(输入:“堆栈溢出”):

输入您的文本:堆栈溢出 2


PS:strlen()返回不带空终止符的字符串长度,不用自己减去。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多