C语言读取打印文件字符串时出现异常字符如何解决
问题原因
打印出异常乱码是代码存在核心缺陷导致的:
- C语言的字符串要求以
\0作为结束标识,你的代码仅申请了和文件长度等大的内存,读入文件内容后没有在末尾追加结束符。用printf配合%s打印时,函数会持续向后读取内存中的随机值,直到碰到随机出现的\0才会停止,这部分越界读取的内存值就是你看到的乱码。 - 缺少必要的错误校验:如果文件打开失败、内存申请失败,
buffer会是未初始化的野指针,直接传入printf会触发未定义行为,轻则乱码重则程序崩溃。另外在Windows平台下,用文本模式"r"打开文件时,系统会自动把换行符\r\n转换为\n,会导致ftell获取的文件长度和实际读取到的字节数存在偏差,进一步引发内存越界问题。
修正方案
对读取逻辑做如下调整即可解决问题:
- 内存申请时多分配1字节空间,专门用来存放字符串结束符
\0,读入内容后手动在末尾设置结束位 - 改用二进制模式
"rb"打开文件,避免换行符转换带来的长度计算偏差 - 增加空指针校验,对
fread的实际读取长度做校验,避免野指针访问 - 用完申请的堆内存后及时释放,避免内存泄漏
修正后的完整代码:
#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
相关产品推荐
相关产品推荐

