【问题标题】:strlen not giving correct string length Cstrlen 没有给出正确的字符串长度 C
【发布时间】:2015-10-01 00:46:44
【问题描述】:

我正在阅读我的字典并打印出单词 + 单词的长度以进行测试。

我使用 strlen 来获取字符串的长度。但是,我得到的数字不正确。我相信 strlen 不计算 \0 字符。

我正在阅读字典中的前 10 个单词。我的预期输出应该是:

W:A L:1
W:A's L:3
W:AA's L:4
W:AB's L:4
W:ABM's L:5
W:AC's L:4
W:ACTH's L:6
W:AI's L:3
W:AIDS's L:6
W:AM's L:4

但这就是我得到的(注意 L: 是如何在另一行的。我认为这就是问题所在):

W:A
 L:2
W:A's
 L:4
W:AA's
 L:5
W:AB's
 L:5
W:ABM's
 L:6
W:AC's
 L:5
W:ACTH's
 L:7
W:AI's
 L:5
W:AIDS's
 L:7
W:AM's
 L:5

下面是我的代码:

FILE* dict = fopen("/usr/share/dict/words", "r"); //open the dictionary for read-only access 
   if(dict == NULL) {
      return;
   }

   int i;
   i = 0;

   // Read each line of the file, and insert the word in hash table
   char word[128];
   while(i < 10 && fgets(word, sizeof(word), dict) != NULL) {
      printf("W:%s L:%d\n", word, (int)strlen(word));

      i++;
   }

【问题讨论】:

  • fgets() 的结果通常包括'\n'。要修剪,请参阅stackoverflow.com/a/28462221/2410359 BTW,格式很好的问题,虽然肯定是重复的。
  • “我相信strlen 不算'\0' 字符。” ——不,它没有,也不应该这样做。 (任何对strlen 函数的引用,包括man strlen,如果您的系统有手册页,都会告诉您这一点。)

标签: c io strlen


【解决方案1】:

fgets() 如果有足够的空间,则将换行符读入缓冲区。因此,当您打印 word 时,您会看到打印的换行符。来自 fgets 手册:

fgets() 从流中最多读入一个小于 size 的字符 并将它们存储到 s 指向的缓冲区中。阅读停止后 EOF 或换行符。 如果读取了换行符,则将其存储到 缓冲。一个终止的空字节('\0')存储在最后一个之后 缓冲区中的字符。

(强调我的)

你必须自己修剪它:

while(i < 10 && fgets(word, sizeof(word), dict) != NULL) {
  size_t len = strlen(word);
  if ( len > 0 &&  word[len-1] == '\n' )  word[len] = '\0';

  printf("W:%s L:%d\n", word, (int)strlen(word));
  i++;
}

【讨论】:

    【解决方案2】:

    原因是因为 fgets 每次都会将换行符 '\n' 拉入缓冲区word,从而导致每次计数都增加 1。

    【讨论】:

    • 读取文件的最后一行时,有尾'\n'的情况并不少见。所以fgets() 并不总是拉入'\n'
    • 所以fgets() 确实会拉入'\n' 如果换行符存在,就像我说的那样。显然,如果文档没有换行符,那么 fgets 将不会生成一个。
    • 另外,如果缓冲区中没有足够的空间来包含换行符,您将在下一个 fgets() 获得它。
    猜你喜欢
    • 1970-01-01
    • 2011-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多