我用这个代码进行了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个问题。如果这有帮助,请告诉我。