sscanf 似乎在 uint 变量和 c 中的 int 变量上表现不同

sscanf seems to behave different on uint variables vs int variables in c

我正在开发一个微控制器程序,想使用 sscanf() 将字符串中的数字读入整数变量。 问题是我在使用 int 声明与 uint8_tuint16_t.

时得到不同的行为

这是使用 int 进行变量声明:

 #include <stdio.h>
 #include <stdint.h>
 int main()
 {
     int power;
     int hr;
     int cadence;
     sscanf("204 67 94","%d %d %d",&power, &hr, &cadence);
     printf("power: %d, hr: %d, cadence: %d", power, hr, cadence);        
     return 0;
 }

当放入https://www.onlinegdb.com/时returns:

power: 204, hr: 67, cadence: 94

...Program finished with exit code 0
Press ENTER to exit console.

这是我期望的行为方式。


而使用 uint8_tuint16_t 整数:

#include <stdio.h>
#include <stdint.h>
int main()
{
    uint16_t power;
    uint8_t hr;
    uint16_t cadence;
    sscanf("204 67 94","%d %d %d",&power, &hr, &cadence);
    printf("power: %d, hr: %d, cadence: %d", power, hr, cadence);
    return 0;
}

当放入 https://www.onlinegdb.com/ 时输出为:

power: 0, hr: 67, cadence: 94

...Program finished with exit code 0
 Press ENTER to exit console.

所以出于某种原因,power(或者更一般地说,似乎是第一个变量)被设置为 0。 谁能给我指出正确的方向并解释我做错了什么?

正确的格式说明符应该是

scanf("%" SCNu16, &power);

使用错误的格式说明符是未定义的行为。您也可以为 sscanf 做同样的事情。

sscanf("204","%"SCNu16 ,&power);

uint8_t 类似,它将是 SCNu8。同样,对于打印,您将使用正确的 -

printf("%" PRIu16 "\n", power);

还可以在启用警告的情况下编译您的代码 -gcc -Wall -Werror progname.c。您看到的警告 - 努力解决它们。那会帮助你解决大问题。查看 sscanf 的手册,了解他们 return 的东西 - 检查它,了解 sscanf 调用是否成功。

%d 格式说明符需要一个指向 int 的指针。如果您使用 %u,对于无符号值,您必须使用 unsigned int。您不能使用 uint16_tuint8_t 等其他类型。也一样:

unsigned int power;
unsigned int hr;
unsigned int cadence;
sscanf("204 67 94","%d %d %d",&power, &hr, &cadence);

在第二个示例中,您对变量类型使用了错误的格式。

您应该使用 <inttypes.h>:

中的宏
 SCNu8   --> uint8_t
 SCNu16  --> uint16_t

uint8_t %hhuuint16_t %hu 可能是安全的。

你的行为很奇怪,因为你欺骗了你的编译器;这就是它获得回报的方式。不要对你的编译器撒谎!

已解决!谢谢

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main()
{
    uint16_t power;
    uint8_t hr;
    uint16_t cadence;
    sscanf("204 67 94","%"SCNu16 "%"SCNu8 "%"SCNu16,&power, &hr, &cadence);
    printf("power: %"PRIu16 " hr: %"PRIu8", cadence: %"PRIu16, power, hr, cadence);
    return 0;
}

这做到了并且产生了预期的输出。 进一步的搜索让我找到了 ,这对我有额外的帮助。