我有以下
unsigned int value = 12;
int res = std::sscanf("-567", "%u", &value);
执行此操作时,res为1表示1匹配,值设置为4294966729 虽然我期待不做任何比赛
如果有人能解释这种行为,我将不胜感激。
答案 0 :(得分:4)
“......其格式与strtoul
函数的主题序列的预期格式相同,基本参数的值为10 ......”
“......如果主题序列以减号开头,则转换产生的值将被否定......”
#include <stdio.h>
int main(void) {
unsigned int value;
int res;
res = sscanf("-567", "%u", &value);
if (res == 1) {
printf("Value: %u\n", value);
} else {
fprintf(stderr, "Error\n");
}
res = sscanf("567", "%u", &value);
if (res == 1) {
value = ~value + 1; // add 1 in two's complement machines
printf("Value: %u\n", value);
} else {
fprintf(stderr, "Error\n");
}
return 0;
}
答案 1 :(得分:1)
这是因为每个负值integere都有其无效的无符号整数值,如果要检查是否输入了正值,则必须将其声明为int类型并检查其值:
long int value:
unsigned int value_ui;
scanf("%ld",&value);
if(value<0)
printf("error");
else
value_ui=(unsigned int) value;
答案 2 :(得分:1)
考虑到你使用std::sscanf()
,你实际上使用的是C ++,而不是C.但是C ++的sscanf()
的行为与C中的行为基本相同。
%u
格式说明符的规范允许包含符号。这基本上意味着将采用模运算。假设有一个32 unsigned int
类型,结果将以模4294967296
为模,以生成0
和4294967295
之间的值。 -567
模4294967296
(也就是-567
除4294967296
后获得的最小正余数)4294966729
。
答案 3 :(得分:0)
如果您浏览sscanf
函数的文档,您会发现sscanf
的返回类型是填充的变量数,在这种情况下基本上是一个,即变量value
。此外,value
显示的数字非常大,因为您在其中存储负整数并以无符号整数格式显示。这将导致模运算,最终结果将是(-567)%(最大无符号整数值)。换句话说,它将是567的两个补码。如果您使用了value
的%d格式说明符,它将仅显示-567。有关sscanf
用法的更多详细信息,请参阅以下链接:
对于C:http://www.tutorialspoint.com/c_standard_library/c_function_sscanf.htm