我正在尝试通过输入到标准输入的字符串选择性地过滤文本文件.
我想知道为什么以下代码不起作用以及如何解决它:
void get_filtered_list()
{
FILE * f;
f=fopen("presentlist.txt","r");
printf("Enter the city by which you want to select lines:\n");
char stringToFind[20];
fgets(stringToFind, sizeof(stringToFind), stdin );
char line[160];
while (!feof(f)){
fgets(line,sizeof(line),f);
if(strstr(line, stringToFind) != NULL)
{
printf("%s",line);
}
}
fclose(f);
}
Run Code Online (Sandbox Code Playgroud)
上面的代码试图获取一个文本文件,打开该文件,然后逐行读取文件,并为执行该strstr()函数的每一行以文件的当前行作为参数1作为字符串,并给出给定的名称城市作为参数2作为字符串.
然而,我得到的结果是打印文件的整个内容(最后一行打印两次,虽然这是一个单独的问题,我知道这部分的修复).
我正在阅读的C书说明该strstr()函数用于在"haystack"字符串中查找"needle"字符串,因此它是C++ substr()函数的C等价物.
strstr() 将参数1作为干草堆,将参数2作为针.
我首先从标准输入读入到针中,然后逐行检查是否strstr()返回NULL(如果在haystack中找不到针,它应该返回NULL)并且如果它返回NULL之外的其他东西,则意味着它找到字符串中的子字符串,它应该只打印行THEN.
而是打印文件中的所有行.为什么?
如果我将其切换为f(strstr(line, stringToFind))相反,那么它绝对不打印.
为什么?
你不会找到字符串,因为你没有去掉尾随'\n'读取到字符串stringToFind通过fgets.实际上,当且仅当它是一行中的最后一个单词时,您才会找到该字符串.
您可以使用以下方法删除换行符:
#include <string.h>
stringToFind[strcspn(stringToFind, "\n")] = '\0';
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以去除换行符,但请注意,如果文件的最后一行没有以换行符结束,缓冲区中将没有填充换行符fgets,因此您不能只覆盖该行的最后一个字符.对于您的问题,最好在开头和结尾删除所有空格字符stringToFind.
还要检查这个问题:为什么"while(!feof(file))"总是错的?
测试文件while (!feof(f))的结尾fgets将太晚捕获文件的结尾:将失败并且您不测试其返回值,因此文件的最后一行似乎将被处理两次.编写此循环的正确方法是:
while (fgets(line, sizeof(line), f)) {
if (strstr(line, stringToFind) != NULL) {
printf("%s",line);
}
}
Run Code Online (Sandbox Code Playgroud)
并不是说长于159字符的行将被拆分fgets并且如果它们包含搜索的字符串将导致错误的输出,特别是如果字符串本身被拆分.
| 归档时间: |
|
| 查看次数: |
3762 次 |
| 最近记录: |