【问题标题】:Out of 3 identical sscanf calls, the middle one does not work在 3 个相同的 sscanf 调用中,中间一个不起作用
【发布时间】:2021-09-11 04:10:22
【问题描述】:

我不知道发生了什么

在我的 C++ 程序中,我只想从命令行读取一些参数。

  1. 变量在 main() 的开头定义:
    uint32_t sampling_frequency;
    uint32_t samples_per_pixel;
    uint32_t total_samples;
    uint16_t amplification;
  1. 在对 argc 进行了一些验证后,我正在阅读它们:
    sscanf(argv[3], "%" PRIu32, &sampling_frequency); 
    sscanf(argv[4], "%" PRIu32, &samples_per_pixel);
    sscanf(argv[5], "%" PRIu16, &amplification);
  1. 紧接着,打印获取的值以进行调试:
    printf("%s: %" PRIu32 "\n", argv[3], sampling_frequency);
    printf("%s: %" PRIu32 "\n", argv[4], samples_per_pixel);
    printf("%s: %" PRIu16 "\n", argv[5], amplification);
  1. 当我运行程序时,大惊喜出现了:
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++ 进行编译。

【问题讨论】:

  • 更陌生,当我以不同的顺序扫描时,我可以让它工作或不工作,但我还是不明白。
  • 第二个sscanf调用的返回值是多少?
  • 我相信对“放大”的读取影响超过 2 个字节。
  • 旁注:由于这是标记为 C++,std::stoul 也可能会有所帮助。例如:uint32_t sampling_frequency = std::stoul(argv[3]);

标签: c++ scanf


【解决方案1】:

PRI* 宏仅适用于打印,不适用于扫描。

如果您想将这些宏与sscanf() 一起使用,您需要使用SCN* 版本。

像这样:

sscanf(argv[3], "%" SCNu32, &sampling_frequency); 
sscanf(argv[4], "%" SCNu32, &samples_per_pixel);
sscanf(argv[5], "%" SCNu16, &amplification);

【讨论】:

  • 啊,是的,当然!我怎么会不记得这个?非常感谢。
【解决方案2】:

您为 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"

因此,您将 PRIu16 宏与 scanf 错误使用会导致您将 4 个字节读入一个 2 个字节的变量。由于您的系统是小端并且可以使用未对齐的访问,因此可以将值正确读取到 uint16_t 中,但也会覆盖接下来的两个内存字节。该内存中究竟是什么取决于编译器如何在堆栈上分配变量,

【讨论】:

    猜你喜欢
    • 2017-08-27
    • 1970-01-01
    • 2015-09-19
    • 2018-01-12
    • 1970-01-01
    • 2014-12-22
    • 2012-08-25
    • 2014-08-17
    • 2020-06-01
    相关资源
    最近更新 更多