【问题标题】:How could SSCANF provide so strange results?SSCANF 怎么会提供如此奇怪的结果?
【发布时间】:2020-07-08 09:24:26
【问题描述】:

我正在与此代码进行为期 4 天的战斗:

  unsigned long baudrate = 0;
  unsigned char databits = 0;
  unsigned char stop_bits = 0;

  char parity_text[10];
  char flowctrl_text[4];

  const char xformat[] = "%lu,%hhu,%hhu,%[^,],%[^,]\n";
  const char xtext[] = "115200,8,1,EVEN,NFC\n";
  int res = sscanf(xtext, xformat, &baudrate, &databits, &stop_bits, (char*) &parity_text, (char*) &flowctrl_text);

  printf("Res: %d\r\n", res);
  printf("baudrate: %lu, databits: %hhu, stop: %hhu,   \r\n", baudrate, databits, stop_bits);
  printf("parity: %s \r\n", parity_text);
  printf("flowctrl: %s \r\n", flowctrl_text);

返回:

分辨率:5
波特率:115200,数据位:0,停止:1,
平价:
flowctrl:NFC

Databitsparity 丢失!

其实parity变量下的内存是'\0'VEN'\0', 看起来第一个字符被 sscanf 过程以某种方式覆盖了。

sscanf 的返回值为 5,这表明它能够解析输入。

我的配置:

  • gccarmnoneeabi 7.2.1
  • Visual Studio 代码 1.43.2
  • PlatformIO Core 4.3.1
  • PlatformIO Home 3.1.1
  • Lib ST-STM 6.0.0 (Mbed 5.14.1)
  • STM32F446RE (Nucleo-F446RE)

我试过了(没有成功):

  • 使用 mbed RTOS 编译,不使用
  • 变量类型 uint8_t, uint32_t
  • gccarm 版本:6.3.1、8.3.1、9.2.1
  • 使用另一个 IDE (CLion+PlatformIO)
  • 在另一台计算机上编译(相同配置)

实际有什么帮助:

  • 将变量设为静态
  • 在 Mbed 在线编译器中编译

sscanf 的行为总体上是非常不可预测的,混合变量的顺序或数据类型有时会有所帮助,但通常以输出中的另一个缺陷结束。

【问题讨论】:

  • 忘记复杂的格式字符串!让它简单,通常不会实现任何更复杂的东西。图书馆必须很小。它不是个人电脑。没有 lu no hhu 没有 [^] 和没有特殊链接器选项的浮点数
  • 正如我所指出的:当使用 Mbed 在线编译器(使用 ARMCC 工具链编译)进行编译时,一切都像魅力一样。相同的内核,相同的设备。特殊链接器选项是什么意思?

标签: std stm32 mbed platformio gnu-arm


【解决方案1】:

这花了我比我愿意承认的更长的时间。但就像大多数问题一样,它最终变得非常简单。

  char parity_text[10];
  char flowctrl_text[4];

需要改成:

  char parity_text[10] = {0};
  char flowctrl_text[5] = {0};

flowctrl_text 数组大小为 4 时不足以容纳“EVEN”和 NULL 终止。如果你把它撞到 5 的大小,你应该没有问题。为了安全起见,我还将数组初始化为 0。

一旦我增加了大小,您现有的代码就会出现 0 个问题。让我知道这是否有帮助。

【讨论】:

  • 我相信我的答案是正确的,但我的变量错误。 flowctrl_text 太小,因为它不能容纳 NFC\n 和 NULL 终止符。纠正此问题后,您应该没有问题。
  • 哇,你说得对。这解释了 NULL 终止符覆盖 parity_text 中的第一个字符。但变量数据位仍然保持为 0。看起来像两个不同的问题。实际上使用“toolchain-gccarmnoneeabi@1.90201.191206”在问题的后半部分被证明是有帮助的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-14
  • 2023-03-22
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多