为什么C语言调用write输出int/double类型时会打印乱码字符?
问题产生原因
write是操作系统提供的底层字节流写入系统调用,它的核心逻辑是将指定内存地址开始、指定长度的原始二进制字节,原封不动写入目标文件描述符,本身不具备任何数值类型到可读文本的格式转换能力。
终端在接收到输出字节流时,会默认按照当前配置的字符编码(如UTF-8)将字节解析为可显示字符。你直接传入int、double类型变量的地址给write,实际写入终端的是这些数值在内存中存储的原生二进制数据:
- 双精度浮点数43在内存中是IEEE 754标准编码的8字节二进制序列,这些字节的组合不符合可打印字符的编码规则,因此终端显示
�E@这类乱码。 - 整数1234在常见的小端序设备上存储为4个字节:
0xd2、0x04、0x00、0x00,其中部分字节是不可打印的控制字符,剩余字节也无法组成合法的编码字符,因此终端只显示单个乱码替换符。
这种直接写入原始二进制的写法本身没有语法错误,如果是向普通文件写入二进制序列化数据是完全合理的,只是输出到终端时不符合终端的文本解析规则,才会出现乱码。
正确实现方式
如果要输出人可读的数值文本,需要先将数值转换为对应的字符串格式,再将字符串的字节通过write写入,也可以直接使用封装了格式转换逻辑的标准库IO函数(如printf)。
参考代码:
#include <unistd.h> #include <stdio.h> int main(int argc, char **argv) { double s = 43; char buf[64]; // 先将浮点数转为字符串 int str_len = snprintf(buf, sizeof(buf), "%.0f\n", s); write(STDOUT_FILENO, buf, str_len); int num = 1234; // 先将整数转为字符串 str_len = snprintf(buf, sizeof(buf), "%d\n", num); write(STDOUT_FILENO, buf, str_len); return 0; }
内容的提问来源于stack exchange,提问作者Rowooz
相关产品推荐
相关产品推荐

