我正在从stdin读取MAC地址(标准十六进制表示法,例如00:11:22:33:44:55),并将它们转换为6字节变量hw_addr作为小数:
u8 hw_addr[6];
scanf("%2x:%2x:%2x:%2x:%2x:%2x", &hw_addr[0], &hw_addr[1], &hw_addr[2], &hw_addr[3], &hw_addr[4], &hw_addr[5]);
唯一的问题是我收到6次扫描警告:
warning: format '%2x' expects type 'unsigned int *', but argument 3 has type 'u8 *'
.....
任何方法摆脱这些警告而不浪费每个字段的int?
答案 0 :(得分:4)
所以你使用的是拥有数十亿字节RAM的机器,你想要保存其中的6个?
如果要保留数百万个mac地址的数组,则应在读取后将它们转换为压缩格式。但是,通过向scanf
()提供规范的注释不会造成任何伤害。
就此而言,如果hw_addr[]
是一个局部变量,那么它实际上根本不使用空格,因为它会在函数返回后重新用于其他本地变量。
由于无法优化所有内容,因此将优化工作重点放在真正重要的事情上非常重要。
答案 1 :(得分:4)
根据我的scanf
联机帮助页
hh Indicates that the conversion will be one of dioux or n and the next pointer is a pointer to a char (rather than int).
所以你想要"%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx"
答案 2 :(得分:2)
警告表明存在严重问题。您正在将指针传递给无符号字节,但scanf函数将向这些指针写入32位。对于前3个值,额外的24位将覆盖hw_addr数组的部分,但对于最后3个值,您将覆盖堆栈上的某些其他变量。
为了避免重大错误,至少需要进行全面定位hw_addr
u8 hw_addr[6+3];
至少会阻止您的代码破坏堆栈。但实际上,您应该只使用正确大小的scanf值,然后将ints转换回无符号字节。
答案 3 :(得分:1)
您正在将unsigned int读入char地址,这可能不是非常便携或安全。只需使用int数组作为缓冲区来读取然后复制到字节数组