使用C语言read函数从标准输入读取整数出现异常结果的原因
为什么用
read()读取输入整数会得到奇怪的结果? 兄弟,我来给你掰扯清楚这个问题——你用read()系统调用读取标准输入的整数,输入34却输出668723,核心原因是**read()根本不会帮你做任何格式转换,它只是原封不动地读字节流**。
先搞懂read()到底在干嘛
read()是操作系统提供的底层系统调用,它的逻辑非常直白:从指定的文件描述符(这里0是标准输入)读取指定字节数的原始数据,直接写入你给的内存地址里,完全不管这些字节代表什么。
当你在终端输入34然后按回车时,你实际输入的是三个ASCII字符:
'3'对应的ASCII码是十进制51(十六进制0x33)'4'对应的ASCII码是十进制52(十六进制0x34)- 换行符
\n对应的ASCII码是十进制10(十六进制0x0A)
而你的代码里用read(0, &a, sizeof(int)),假设你的系统是小端序(绝大多数现代电脑都是),且int占4个字节,那么read()会把这三个输入字节,再加上一个默认填充的空字节(0x00),按顺序塞进a的内存里。
小端序下,字节是按「低字节在前」的顺序存储的,所以a的内存布局是:0x33 → 0x34 → 0x0A → 0x00
把这四个字节转换成十进制整数就是:0x000A3433 = 668723——这就是你看到的奇怪结果!
怎么解决这个问题?
有两种靠谱的方式:
- 用标准库的格式化输入函数:如果只是要读取整数,直接用
scanf("%d", &a)就好,它会自动把输入的ASCII字符串转换成二进制整数,完全不用你操心:
#include <stdio.h> int main() { int a = 0; scanf("%d", &a); printf("a = %d\n", a); }
- 手动用
read()处理转换:如果你非要用read(),就得自己把读取到的ASCII字符转换成整数,比如逐个字符解析:
#include <unistd.h> #include <stdio.h> #include <ctype.h> int main() { char buf[10]; // 读取输入到缓冲区,留一个位置加字符串结束符 ssize_t n = read(0, buf, sizeof(buf)-1); if (n <= 0) { perror("read failed"); return 1; } buf[n] = '\0'; // 手动添加字符串结束标记 int a = 0; // 逐个字符解析成整数 for (int i = 0; buf[i] != '\0' && isdigit(buf[i]); i++) { a = a * 10 + (buf[i] - '0'); // ASCII码转数字:'0'的ASCII是48,所以减48就是对应数字 } printf("a = %d\n", a); }
内容的提问来源于stack exchange,提问作者zell
相关产品推荐
相关产品推荐

