sscanf 似乎在 uint 变量和 c 中的 int 变量上表现不同
sscanf seems to behave different on uint variables vs int variables in c
我正在开发一个微控制器程序,想使用 sscanf()
将字符串中的数字读入整数变量。
问题是我在使用 int
声明与 uint8_t
或 uint16_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_t
和 uint16_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_t
或 uint8_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
%hhu
和 uint16_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;
}
这做到了并且产生了预期的输出。
进一步的搜索让我找到了 ,这对我有额外的帮助。
我正在开发一个微控制器程序,想使用 sscanf()
将字符串中的数字读入整数变量。
问题是我在使用 int
声明与 uint8_t
或 uint16_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_t
和 uint16_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_t
或 uint8_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
%hhu
和 uint16_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;
}
这做到了并且产生了预期的输出。 进一步的搜索让我找到了 ,这对我有额外的帮助。