C语言文件操作程序报错‘Can't read’问题排查请求
问题分析与修复方案
Hey there! Let's break down why your code is showing the "Can't read" message and fix all the issues step by step:
主要问题点
1. feof() 的错误使用
你的循环条件用了 while (!feof(fis)),但 feof() 只有在读取操作失败后才会返回非零值。这意味着当文件读到最后一行时,循环会多执行一次:此时 fgets() 已经无法读取内容,返回 NULL,触发了你写的 "Can't read!" 提示。
正确的做法是直接用 fgets() 的返回值作为循环条件,这样当读取到文件末尾或者出错时,循环会直接终止。
2. 字符串比较错误
rez == word 是在比较两个指针的地址,而不是字符串的内容!你想判断的是当前行是否包含输入的单词,应该用 strstr() 函数(需要包含 <string.h> 头文件)来检查 rez 中是否存在 word 这个子串。
3. Exit.txt 的打开方式错误
每次找到匹配行时,你用 fopen("Exit.txt", "wt") 打开文件,wt 模式会清空文件原有内容,最终只会保留最后一行匹配的内容。应该用追加模式 "at",或者更高效的方式:在循环前就打开 Exit.txt,循环结束后再关闭它。
4. gets() 函数不安全
gets() 没有缓冲区边界检查,容易导致缓冲区溢出,是已被废弃的函数。建议用 fgets() 替代,同时要处理掉输入时的换行符(fgets() 会把换行符也读入字符串)。
5. 文件资源泄漏与空指针访问
- 如果
fis打开失败(fis == NULL),后续的fclose(fis)会访问空指针,导致未定义行为。 fis2打开后没有关闭,会导致文件资源泄漏。
修正后的代码
#include<stdio.h> #include<stdlib.h> #include<string.h> // 新增:用于strstr和strcspn函数 int main() { FILE* fis = NULL, * fis2 = NULL; char* sir = NULL; char word[50]; printf("Word: "); // 替换gets为fgets,同时去掉换行符 fgets(word, sizeof(word), stdin); word[strcspn(word, "\n")] = '\0'; // 移除输入末尾的换行符 // 分配内存 sir = malloc(50 * sizeof(char)); if (sir == NULL) { printf("Memory allocation failed!\n"); return 1; } // 打开输入文件 fis = fopen("In.txt", "rt"); if (fis == NULL) { printf("Can't open file!\n"); free(sir); return 1; } // 打开输出文件(追加模式,避免清空原有内容) fis2 = fopen("Exit.txt", "at"); if (fis2 == NULL) { printf("Can't open output file!\n"); fclose(fis); free(sir); return 1; } // 正确的读取循环:用fgets的返回值判断 while (fgets(sir, 50, fis) != NULL) { // 检查当前行是否包含目标单词 if (strstr(sir, word) != NULL) { fputs(sir, fis2); // 写入匹配的行 } } // 关闭所有打开的文件 fclose(fis); fclose(fis2); free(sir); printf("Search completed successfully!\n"); return 0; }
关键修改说明
- 用
fgets()替代gets(),并处理换行符,避免字符串包含不必要的换行。 - 把
feof()循环改成fgets()返回值判断,彻底解决"Can't read"的误触发。 - 用
strstr()检查行中是否包含目标单词,实现正确的匹配逻辑。 - 提前打开
Exit.txt并使用追加模式,确保所有匹配行都被保留。 - 增加了内存分配和文件打开的错误检查,避免空指针访问和资源泄漏。
内容的提问来源于stack exchange,提问作者user14074667
相关产品推荐
相关产品推荐

