摆脱sscanf()警告

时间:2010-02-17 04:06:32

标签: c scanf

我正在从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?

4 个答案:

答案 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数组作为缓冲区来读取然后复制到字节数组