如何对比从stdin读取的2字节数据与0x0001、0x0002等十六进制数值
核心问题原因
- 输入格式和读取逻辑不匹配:
read函数读取的是标准输入的原始二进制字节,如果你是通过终端输入字符形式的0001,读取到的是四个字符对应的ASCII码(0对应0x30,1对应0x31),前两字节拼接后值为0x3030,和预期的0x0001完全不符。 - 字节序问题:即便你输入的是二进制2字节数据,不同CPU架构的大小端存储规则不同,也可能出现数值转换错误。比如小端架构的x86平台,低字节存储在前,若输入二进制是大端序的
0x00 0x01,读取到的type值会是0x0100。
解决方法
场景1:输入为文本格式的数字(比如终端输入1、0x0001)
直接使用标准库的格式化输入函数读取即可,不需要处理原始字节:
#include <stdio.h> #include <stdint.h> int main() { uint16_t type; // 读取十六进制格式输入用%hx,读取十进制格式输入替换为%hu while (scanf("%hx", &type) == 1) { if (type == 0x0001) { // 第一类逻辑 } else if (type == 0x0002) { // 第二类逻辑 } } return 0; }
场景2:输入为2字节原始二进制流
首先保证输入源是二进制数据(比如通过管道、文件传入二进制流,不要用终端输入字符),其次补充字节序转换逻辑保证兼容不同架构:
#include <unistd.h> #include <stdint.h> #include <endian.h> int main() { uint16_t type; // 确保读取到完整的2字节再处理 while (read(STDIN_FILENO, &type, sizeof(type)) == sizeof(type)) { // 如果输入二进制是大端序(网络字节序默认大端)用be16toh转换 uint16_t host_type = be16toh(type); // 如果输入二进制是小端序替换为le16toh(type) if (host_type == 0x0001) { // 第一类逻辑 } else if (host_type == 0x0002) { // 第二类逻辑 } } return 0; }
内容的提问来源于stack exchange,提问作者Nikolay Georgiev
相关产品推荐
相关产品推荐

