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

C语言读取文件到512长字符数组 剩余空位填'x'代码问题排查

代码存在的核心问题
  • 未初始化字符数组:栈上分配的str[512]默认存储随机垃圾值,不会自动填充'\0',原有填充逻辑靠找'\0'判断有效内容结尾完全不成立,没被写入的位置本身就是乱码,输出自然混乱。
  • 文件读取逻辑存在多个漏洞:
    • 没有判断fopen返回值,文件不存在、无读取权限时直接操作空指针会直接崩溃
    • 用while(!feof(fp))做循环条件是C语言经典错误写法,feof只有在读操作已经碰到EOF之后才会返回真值,会导致多读取一次无效的EOF值
    • 写入数组时没做长度校验,一旦文件内有效小写字母数量超过512,就会发生数组越界写,破坏相邻内存数据
    • 传给tolower的参数没做类型强转,遇到编码值为负的字符会触发未定义行为
    • 读完文件没有调用fclose,存在资源泄漏
  • 填充逻辑设计错误:原有逻辑从下标0开始遍历数组找'\0',但数组未初始化时大部分位置是随机值不是'\0',这些位置根本不会被替换成'x';实际上读取循环结束时,变量i的值刚好就是有效字符的总长度,直接从这个位置开始填充即可,完全不需要遍历全数组找结尾。
可直接运行的修正版本
#include <stdio.h>
#include <ctype.h>

int main() {
    FILE *fp;
    char str[512];
    int c, i = 0;

    fp = fopen("k1.txt", "r");
    if (fp == NULL) {
        perror("文件打开失败");
        return 1;
    }

    // 读入时同步做长度限制,避免越界,直接判断fgetc返回值替代错误的feof判断
    while (i < 512 && (c = fgetc(fp)) != EOF) {
        c = tolower((unsigned char)c);
        // 仅保留小写字母,其余字符全部跳过
        if (c >= 'a' && c <= 'z') {
            str[i] = c;
            i++;
        }
    }
    fclose(fp);

    // 从有效内容末尾开始填充'x'直到数组满512位
    for (; i < 512; i++) {
        str[i] = 'x';
    }

    // 如需验证结果可放开下方注释打印数组内容
    // for (int j = 0; j < 512; j++) putchar(str[j]);
    return 0;
}
关键修改说明
  • 补全了依赖的头文件,避免隐式函数声明导致的编译警告、运行异常
  • 增加文件打开失败的判断逻辑,提前报错退出
  • 重写读取循环条件,直接判断fgetc返回值是否为EOF,同时加入i < 512的边界限制,从根源杜绝数组越界
  • 去掉冗余的换行判断,tolower传参时强转为unsigned char规避未定义行为
  • 读取结束后立刻关闭文件释放资源
  • 填充'x'时直接从有效长度i的位置开始写入,直到数组最后一个下标(511)为止,不依赖数组初始值,保证数组后段全部被填充为'x',总长度刚好512。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 13:33:10