0

我正在编写一个程序,它打开两个文件进行读取:第一个文件包含 20 个名称,我将它们存储在表单的数组中Names[0] = John\0。第二个文件是一个大文本文件,其中包含 20 个名称中每个名称的多次出现。

我需要我的程序扫描第二个文件的整个内容,每次找到其中一个名称时,Count都会增加一个变量,以此类推,在程序完成后,文本中出现的所有名称的总数存储在Count.

这是我的循环,它搜索并计算名称出现的次数:

char LineOfText[85];
char *TempName;    

while(fgets(LineOfText, sizeof(LineOfText), fpn)){
    for(a = 0; a<NumOfNames; a++){
        TempName = strstr(LineOfText, Names[a]);
        if(TempName != NULL){
            Count++;
        }
    }
}

无论我做什么,这个循环都不会像我期望的那样工作,但我发现了问题所在(我认为!)。我的问题是数组中的每个名称都以 NULL 结尾,但是当名称出现在文本文件中时,它不是以 NULL 结尾的,除非它作为一行的最后一个单词出现。因此,此while循环仅计算任何名称出现在行尾的次数,而不是任何名称在文本文件中任何位置出现的次数。如何调整这个循环来解决这个问题?

感谢您提前提供任何建议。

4

2 回答 2

1

这里的问题可能是您使用fgets,它不会它读取的行中修剪换行符。

如果您names通过读取带有 的行来创建数组fgets,则所有名称都将以换行符终止。正在读取的文件中的fgets行也将以换行符终止,因此名称只会在行尾匹配。

strstr出于显而易见的原因,不比较终止模式字符串的 NUL 字节。如果是这样,它只会匹配后缀字符串,这将使它成为一个非常不同的函数。

此外,您最多只能在每一行中找到每个名称的一个实例。如果您认为一个名称可能在同一行中出现多次,您应该替换:

 TempName = strstr(LineOfText, Names[a]);
 if(TempName != NULL){
    Count++;
 }

有类似的东西:

 for (TempName = LineOfText;
      (TempName = strstr(TempName, Names[a]);
     ++Count, ++TempName) {
 }

作为参考,这里是fgets来自 C 标准的定义(强调添加):

该函数最多从 指向的流中fgets读取比 指定的字符数少 1 到指向的数组。在换行符(保留)之后或文件结尾之后不会读取其他字符。在读入数组的最后一个字符之后立即写入一个空字符。nstreams

这与gets不保留换行符的 不同。

于 2015-05-05T13:52:45.577 回答
0

我认为 names 数组的 NULL 终止不是问题(请参阅 strstr 函数参考)。该strstr函数不会比较终止符。您确实有可能在每一行上丢失其他名称。请参阅下面的调整示例,了解如何在每行计算多个名称。

char LineOfText[85];
char *TempName;    

while(fgets(LineOfText, sizeof(LineOfText), fpn)){
    for(a = 0; a<NumOfNames; a++){
        TempName = strstr(LineOfText, Names[a]);

        /* Iterate through line for multiple occurrences of each name */
        while(TempName != NULL){
            Count++;

            /* Get next occurrence of name on line. fgets is going to
               leave a newline at the end of the LineOfText string so
               unless some of your names contain a newline, it shouldn't
               move past the end of the buffer */
            TempName = strstr(TempName + 1, Names[a]);
        }
    }
}
于 2015-05-05T13:54:17.243 回答