You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 19:22:35