我不知道发生了什么
在我的 C++ 程序中,我想简单地从命令行读取一些参数。
uint32_t sampling_frequency;
uint32_t samples_per_pixel;
uint32_t total_samples;
uint16_t amplification;
sscanf(argv[3], "%" PRIu32, &sampling_frequency);
sscanf(argv[4], "%" PRIu32, &samples_per_pixel);
sscanf(argv[5], "%" PRIu16, &lification);
printf("%s: %" PRIu32 "\n", argv[3], sampling_frequency);
printf("%s: %" PRIu32 "\n", argv[4], samples_per_pixel);
printf("%s: %" PRIu16 "\n", argv[5], amplification);
4.b:~/pro/spectr> ./spectr spectr_02.png out.wav 44100 10 2 -9 -8 -5 -4 -2 0 2 3 5
44100: 44100
10: 0
2: 2
如您所见,3 个 sscanf() 是相同的,但由于某些无法解释的原因,它仅对 argv[4] 无法正常工作。 问题出在 sscanf() 而不是 printf(),因为代码稍后检查数值并且它的行为确实就像是 0。 我不知道为什么它会这样。
我在 Debian10 amd64 上使用 g++ 进行编译。
PRI*
宏仅适用于打印,不适用于扫描。
如果您想将这些宏与
sscanf()
一起使用,则需要使用 SCN*
版本。
像这样:
sscanf(argv[3], "%" SCNu32, &sampling_frequency);
sscanf(argv[4], "%" SCNu32, &samples_per_pixel);
sscanf(argv[5], "%" SCNu16, &lification);
您对 scanf 使用了错误的格式说明符宏。 “PRI”宏适用于 printf 系列。 “SCN”宏适用于 scanf 系列。
由于整数提升适用于可变参数,因此 printf 仅需要大于 int 的类型的大小说明符。对于小于 int 的类型和大于 int 的类型,scanf 都需要它们。
您的平台有一个 32 位 int 和一个 16 位 Short。所以宏可能类似于 .
#define PRIu16 "u"
#define PRIu32 "u"
#define SCNu16 "hu"
#define SCNu32 "u"
因此,您对 scanf 的 PRIu16 宏的错误使用会导致您将 4 个字节读取到 2 个字节的变量中。由于您的系统是小端字节序并且可以接受未对齐的访问,因此可以将值正确读取到 uint16_t 中,但也会覆盖内存的接下来两个字节。该内存中到底有什么取决于编译器如何在堆栈上分配变量,
在您的情况下,似乎
amplification
直接分配在 samples_per_pixel
下面。因此,将四字节值读入 amplification
会覆盖 samples_per_pixel
的前两个字节。