1

我正在从标准输入读取 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 个 scanf 警告:

warning: format '%2x' expects type 'unsigned int *', but argument 3 has type 'u8 *'

......

有什么方法可以在不浪费每个字段的 int 的情况下摆脱这些警告?

4

4 回答 4

4

只需使用正确的类型

所以你正在使用一台拥有数十亿字节 RAM 的机器,你想节省其中的 6 个?

如果您要保留数百万个 mac 地址的数组,则应在读取它们后将它们转换为打包格式。scanf但是向()提供规范的整数并没有什么坏处。

就此而言, ifhw_addr[]是一个局部变量,那么它实际上根本不使用任何空间,因为它会在您的函数返回后被其他局部变量重用。

由于您无法优化所有内容,因此将优化工作集中在真正重要的事情上很重要。

于 2010-02-17T04:14:17.083 回答
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"

于 2010-02-17T04:21:28.583 回答
2

这些警告表明存在严重问题。您正在传递指向无符号字节的指针,但 scanf 函数将向这些指针写入 32 位。对于前 3 个值,额外的 24 位将覆盖 hw_addr 数组的部分,但对于最后 3 个值,您将覆盖堆栈上的其他一些变量。

为了避免严重的崩溃,至少你需要过度分配 hw_addr

u8 hw_addr[6+3];

至少可以防止您的代码破坏堆栈。但实际上,您应该只使用正确大小的 scanf 值,然后从整数转换回无符号字节。

于 2010-02-17T04:22:38.040 回答
1

您正在将 unsigned int 读入 char 地址,这可能不是很便携或安全。只需使用 int 数组作为缓冲区读取然后复制到字节数组

于 2010-02-17T04:14:20.517 回答