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

从文本文件中移除指定字符串数组内单词的C语言代码故障排查求助

解决文件单词过滤代码的问题

我来帮你看看这段代码的问题所在,你想要实现的是从每行一个单词的文件里过滤掉指定单词,输出剩下的到新文件,但代码里有几个关键逻辑和写法问题导致不符合预期:

原代码的核心问题

  • while(!feof(inp))的错误用法:这个判断会导致最后一行被重复处理,因为feof只有在读取操作尝试读取到文件末尾之后才会置位。当最后一次fgets成功读取后,循环还会再执行一次,此时fgets会失败,但word里保留的是上一次的内容,导致错误处理。
  • 循环逻辑混乱:你在while循环里嵌套了for循环,每次for循环迭代都调用fgets,这意味着一次while循环会读取13个单词(除非中途强制跳出),完全不符合“逐行读取并检查”的逻辑。而且在else分支里设置i=14跳出for循环的写法不仅不规范,还会打乱循环的正常流程。
  • 字符串数组空间不足:你定义toremove[][5],但像"that\n"这样的字符串,加上结束符'\0'需要6个字节的空间(t、h、a、t、\n、\0),数组的5字节空间会导致字符串被截断,没有正确的终止符,strcmp无法正确匹配这些字符串,自然匹配不到你想移除的单词。
  • 没有写入输出文件:代码里只有printf调试输出,完全没有把符合条件的单词写入到outp指向的out2.dat.txt文件里。

修正后的代码

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>

int main(void) {
    FILE *inp;
    FILE *outp;
    char word[16];
    // 用指针数组存储要移除的单词,避免空间不足问题
    const char *toremove[] = {"is\n", "a\n", "and\n", "with\n", "By\n", "that\n", "to\n", "It\n", "has\n", "in\n", "for\n", "from\n"};
    // 计算要移除的单词数量,避免硬编码数字
    int remove_count = sizeof(toremove) / sizeof(toremove[0]);

    // 打开文件时检查是否成功,避免后续操作崩溃
    inp = fopen("out1.dat.txt", "r");
    if (inp == NULL) {
        perror("Failed to open input file");
        return EXIT_FAILURE;
    }

    outp = fopen("out2.dat.txt", "w");
    if (outp == NULL) {
        perror("Failed to open output file");
        fclose(inp); // 已打开的输入文件要及时关闭
        return EXIT_FAILURE;
    }

    // 正确的逐行读取循环:fgets成功读取内容时进入循环
    while (fgets(word, sizeof(word), inp) != NULL) {
        bool should_remove = false;
        // 遍历过滤词列表,检查当前行是否需要移除
        for (int i = 0; i < remove_count; i++) {
            if (strcmp(word, toremove[i]) == 0) {
                should_remove = true;
                break; // 找到匹配就跳出循环,不用继续检查
            }
        }
        // 如果不需要移除,就写入输出文件
        if (!should_remove) {
            fputs(word, outp);
            printf("保留单词:%s", word); // 调试用输出,可按需删除
        } else {
            printf("移除单词:%s", word); // 调试用输出,可按需删除
        }
    }

    // 关闭所有打开的文件
    fclose(inp);
    fclose(outp);
    return EXIT_SUCCESS;
}

关键改动说明

  • 替换错误的循环条件:用fgets的返回值作为循环条件,确保只有成功读取到一行内容时才处理,避免末尾重复或错误。
  • 改用指针数组存储过滤词:const char *toremove[]可以正确存储任意长度的字符串(只要不超过word的长度),解决了原数组空间不足导致的字符串截断问题。
  • 重构检查逻辑:逐行读取后,遍历过滤词列表判断是否需要移除,逻辑清晰,不会出现原代码中一次读取多个单词的问题。
  • 增加文件打开错误检查:避免文件打开失败时程序继续执行导致的崩溃。
  • 实现输出文件写入:用fputs把不需要移除的单词写入到out2.dat.txt,完成你原本的需求。

内容的提问来源于stack exchange,提问作者Tom Snow

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 18:12:34