搜索在非空的文件中以NULL结尾的字符串终止

时间:2015-05-05 13:40:50

标签: c null fgets null-terminated

我正在编写一个打开两个文件进行阅读的程序:第一个文件包含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循环仅计算任何名称出现在行尾的次数,而不是文本文件中任何位置的任何名称的出现次数。如何调整此循环以解决此问题?

提前感谢您的任何建议。

2 个答案:

答案 0 :(得分: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) {
 }

供参考,以下是C标准中fgets的定义(强调添加):

  

fgets函数从n指向的流中将stream指定的字符数最多读取一个小于s指向的数组。在换行符(保留)之后或文件结束后,不会读取其他字符。在读入数组的最后一个字符后立即写入空字符。

这与gets不同,<p style="font-size:6pt">&#160;</p>不保留换行符。

答案 1 :(得分:0)

我认为名称数组的NULL终止不是问题(See strstr function reference)。 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]);
        }
    }
}