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