为什么 sscanf %lx 在 64 位环境中读取任何第一个 uint32_t 的“0”?
Why does sscanf %lx read "0" for any first uint32_t on a 64-bit environment?
我有以下 C 代码:
uint32_t a = 1, b = 2;
sscanf("0xbadf00d 0xdeadbeef", "%lx %lx", &a, &b);
printf("%lx %lx", a, b);
在使用 gcc 的 64 位 Linux 机器上,如果我使用标志 -m32
进行编译,我会得到正确的输出:badf00d deadbeef
,但默认情况下我会得到奇怪的输出0 deadbeef
。
第二种情况是怎么回事?我是不是使用了错误的转换说明符字符,或者,有没有办法在没有此编译器标志的情况下解决问题?
您正在使用 l
长度修饰符,它适用于 unsigned long
,但 uint32_t
在 64 位上 不是 unsigned long系统,唯一的例外是 Windows。没有定义 uint32_t
的标准长度修饰符,但是 header 中有包含长度修饰符(通常是空字符串)的宏。
可移植的解决方案是使用 <inttypes.h>
:
中定义的宏
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
int main() {
uint32_t a = 1, b = 2;
sscanf("0xbadf00d 0xdeadbeef", "%" SCNx32 " %" SCNx32, &a, &b);
printf("%" PRIx32 " %" PRIx32, a, b);
}
在您实际使用的几乎所有系统上,在宏扩展后,这与以下内容相同:
#include <stdint.h>
#include <stdio.h>
int main() {
uint32_t a = 1, b = 2;
sscanf("0xbadf00d 0xdeadbeef", "%x %x", &a, &b);
printf("%x %x", a, b);
}
我有以下 C 代码:
uint32_t a = 1, b = 2;
sscanf("0xbadf00d 0xdeadbeef", "%lx %lx", &a, &b);
printf("%lx %lx", a, b);
在使用 gcc 的 64 位 Linux 机器上,如果我使用标志 -m32
进行编译,我会得到正确的输出:badf00d deadbeef
,但默认情况下我会得到奇怪的输出0 deadbeef
。
第二种情况是怎么回事?我是不是使用了错误的转换说明符字符,或者,有没有办法在没有此编译器标志的情况下解决问题?
您正在使用 l
长度修饰符,它适用于 unsigned long
,但 uint32_t
在 64 位上 不是 unsigned long系统,唯一的例外是 Windows。没有定义 uint32_t
的标准长度修饰符,但是 header 中有包含长度修饰符(通常是空字符串)的宏。
可移植的解决方案是使用 <inttypes.h>
:
#include <stdint.h>
#include <stdio.h>
#include <inttypes.h>
int main() {
uint32_t a = 1, b = 2;
sscanf("0xbadf00d 0xdeadbeef", "%" SCNx32 " %" SCNx32, &a, &b);
printf("%" PRIx32 " %" PRIx32, a, b);
}
在您实际使用的几乎所有系统上,在宏扩展后,这与以下内容相同:
#include <stdint.h>
#include <stdio.h>
int main() {
uint32_t a = 1, b = 2;
sscanf("0xbadf00d 0xdeadbeef", "%x %x", &a, &b);
printf("%x %x", a, b);
}