Xcode环境下C语言fwrite()与fread()函数运行异常求助
C语言fwrite写入文件显示乱码问题排查
问题根因
你看到的乱码不是fread()/fwrite()函数工作异常,是使用方式和预期不匹配导致的正常现象:
fwrite()和fread()是二进制读写函数,作用是把内存中存储的原始字节流原封不动写入文件、或从文件原封不动读回内存,不会自动把数值类型转换成人类可读的文本格式。- 你代码中写入的是
Product结构体的内存内容,也就是两个float类型的IEEE754格式二进制浮点数,总计8字节的原始二进制数据。用文本编辑器打开文件时,编辑器会强行把这些二进制字节按文本编码(UTF-8/ASCII等)解析成字符,最终显示的就是你看到的乱码。
修正方案
根据你的实际需求二选一即可:
需要写入可直接阅读的文本内容
不要用fwrite(),改用fprintf()做格式化输出,文件打开模式用普通文本写模式"w"即可,修正后代码示例:#include <stdio.h> typedef struct Product { float size; float price; } Product; int main() { Product my_prod; my_prod.price = 13.2; my_prod.size = 10.3; FILE* file_in = fopen("/Users/piton/Desktop/UniverProg/Test/Test/input.txt", "w"); if (file_in == NULL) { printf("ERROR: failed to open file"); return 1; // 打开失败直接退出,避免空指针访问 } // 格式化写入可读文本 fprintf(file_in, "size: %.1f\nprice: %.1f\n", my_prod.size, my_prod.price); fclose(file_in); return 0; }运行后打开文件就能看到正常的数字文本,不会有乱码。
需要存储二进制数据(供程序后续直接读回结构体,读写效率更高)
你原本的逻辑是对的,只需要修正两个问题:- 二进制读写时,
fopen()的模式参数要加二进制标识b,写入用"wb",读取用"rb",避免跨平台时换行符转义破坏二进制数据(Mac/Linux下文本和二进制模式无差异,但加b是跨平台兼容的规范写法) - 文件打开失败后要直接退出程序,不要继续执行读写操作
写入修正后不用在意文本编辑器打开看到的乱码,只要读取时用对应二进制模式,用fread()整块读回结构体,拿到的数值就是完全正确的,读取示例:
Product read_prod; FILE* fp = fopen("/Users/piton/Desktop/UniverProg/Test/Test/input.txt", "rb"); if (fp == NULL) { printf("ERROR: failed to open file"); return 1; } fread(&read_prod, sizeof(Product), 1, fp); // 此处打印会正常输出 size:10.3, price:13.2 printf("size:%.1f, price:%.1f\n", read_prod.size, read_prod.price); fclose(fp);- 二进制读写时,
内容的提问来源于stack exchange,提问作者Vladyslav
相关产品推荐
相关产品推荐

