SSCANF怎么能提供如此奇怪的结果



我用这个代码进行了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,NFCn";
int res = sscanf(xtext, xformat, &baudrate, &databits, &stop_bits, (char*) &parity_text, (char*) &flowctrl_text);
printf("Res: %drn", res);
printf("baudrate: %lu, databits: %hhu, stop: %hhu,   rn", baudrate, databits, stop_bits);
printf("parity: %s rn", parity_text);
printf("flowctrl: %s rn", flowctrl_text);

它返回:

Res:5
波特率:115200,数据位:0,停止:1,
奇偶校验:
flowctrl:NFC

数据位奇偶校验丢失!

实际上,奇偶校验变量下的内存为'\0'VEN'\0',看起来第一个字符被sscanf过程以某种方式覆盖了。

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

我的配置:

  • gccarmononeeabi 7.2.1
  • Visual Studio代码1.43.2
  • PlatformIO核心4.3.1
  • PlatformIO主页3.1.1
  • Lib ST-STM 6.0.0(姆贝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的行为总体上是非常不可预测的,混合变量的顺序或数据类型有时会有所帮助,但最常见的是输出中的另一个缺陷。

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

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

需要更改为:

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

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

一旦我增加了大小,你现有的代码就出现了0个问题。如果这有帮助,请告诉我。

最新更新