字典中单词数量的越界问题

编程语言 2026-07-09

我在做CS50x的第5 组作业题(problem set 5)。这段代码打开一个字典,用fgets() 将每个单词读入,然后把计数加1 以统计总单词数。总共有143091个单词,但这段代码却总是返回143092。

我用同样的代码在一个要小得多、只有两个单词的文件上测试过,代码正确地把它统计为2。

#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    // Open files
    FILE *mydictionary = fopen("dictionaries/large", "r");
    if (mydictionary == NULL)
    {
        fclose(mydictionary);
        return 1;
    }

    // Variables
    char word[45];
    int count = 0;

    // Count words
    while (true)
    {
        if (fgets(word, 45, mydictionary) == NULL || isspace(word[0]))
        {
            break;
        }
        count++;
    }

    printf("%i\n", count);
}

字典文件

解决方案

根据规范,这个字典中的单词都不超过45个字符。

你必须考虑换行符,以及由 fgets 添加的NUL字符。如果最长的单词有45个字符,你的缓冲区必须留出47个字符的空间。

字典确实包含一行有45个字符的单词:

         1         2         3         4     4
1234567890123456789012345678901234567890123456
pneumonoultramicroscopicsilicovolcanoconiosis␊

包括换行符在内,这一行共有46个字符。

fgets 在一次遍历中把前44个字符和一个NUL放入 word,在下一次遍历中再放入单词的最后一个字符、换行符和一个NUL。因此这行将计数增加两次。

将缓冲区大小增加到47(或使用一种不需要事先知道最大单词长度的做法)。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章