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

C语言读取打印文件字符串时出现异常字符如何解决

问题原因

打印出异常乱码是代码存在核心缺陷导致的:

  • C语言的字符串要求以\0作为结束标识,你的代码仅申请了和文件长度等大的内存,读入文件内容后没有在末尾追加结束符。用printf配合%s打印时,函数会持续向后读取内存中的随机值,直到碰到随机出现的\0才会停止,这部分越界读取的内存值就是你看到的乱码。
  • 缺少必要的错误校验:如果文件打开失败、内存申请失败,buffer会是未初始化的野指针,直接传入printf会触发未定义行为,轻则乱码重则程序崩溃。另外在Windows平台下,用文本模式"r"打开文件时,系统会自动把换行符\r\n转换为\n,会导致ftell获取的文件长度和实际读取到的字节数存在偏差,进一步引发内存越界问题。
修正方案

对读取逻辑做如下调整即可解决问题:

  1. 内存申请时多分配1字节空间,专门用来存放字符串结束符\0,读入内容后手动在末尾设置结束位
  2. 改用二进制模式"rb"打开文件,避免换行符转换带来的长度计算偏差
  3. 增加空指针校验,对fread的实际读取长度做校验,避免野指针访问
  4. 用完申请的堆内存后及时释放,避免内存泄漏

修正后的完整代码:

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

char *readFile(char *filename)
{
    char *buffer = NULL;
    long length;
    FILE *f = fopen(filename, "rb");
    if (f)
    {
        fseek(f, 0, SEEK_END);
        length = ftell(f);
        fseek(f, 0, SEEK_SET);
        // 多申请1字节存字符串结束符
        buffer = malloc(length + 1);
        if (buffer)
        {
            size_t read_len = fread(buffer, 1, length, f);
            // 手动追加字符串结束标记
            buffer[read_len] = '\0';
        }
        fclose(f);
    }
    return buffer;
}

int main() {
    char *firstS = readFile("file.txt");
    if (firstS) {
        printf("%s \n", firstS);
        free(firstS); // 释放堆内存避免泄漏
    } else {
        printf("文件读取失败\n");
        return 1;
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:57:29