#include<stdio.h>
main()
{
unsigned int num;
printf("enter the number:\n");
scanf("%u",&num);//4294967299 if i'm scanning more than 4G its not scanning
printf("after scanning num=%u\n",num);// 4294967295 why its giving same 4G
/* unsigned char ch;
printf("enter the character:\n");
scanf("%d",&ch);// if i/p=257 so its follow circulation
printf("after scanning ch=%d\n",ch);// 1 its okk why not in int ..
*/
}
为什么在通过scanf()
扫描输入时没有关注循环,为什么在char
的情况下会关注?
答案 0 :(得分:6)
C11标准草案n1570 7.21.6.2说明如下
[...]输入项[...]转换为适合转换说明符的类型。如果输入项不是匹配序列,则指令的执行失败:此条件是匹配失败。除非
*
指示赋值抑制,否则转换的结果将放在由尚未收到转换结果的format参数后面的第一个参数指向的对象中。如果此对象没有合适的类型,或者无法在对象中表示转换结果,则行为未定义。
现在,&#34;转换&#34;这里用于string =&gt;结果数据类型转换,不能理解为整数转换。由于转换为十进制整数的字符串"4294967299"
在32位宽的unsigned int
类型的对象中无法表示,因此标准的读取表明行为未定义,即
使用不可移植或错误的程序结构或错误数据的行为,本国际标准没有规定
因此,您的问题的答案是C标准在这种情况下没有说明行为,您看到的行为是您的编译器和C库实现的行为,并且不可移植;在其他平台上,可能的行为可能包括:
完全忽略不可预测的结果的情况,在翻译或程序执行过程中以文档化的方式表现环境(有或没有发出诊断消息),终止翻译或执行(发布诊断消息)。
答案 1 :(得分:-4)
this scanf
(and family) reference格式为"%u"
:
数字的格式与
strtoul()
的预期相同,基本参数的值为0
(基数由解析的第一个字符决定)
然后我们转到strtoul
函数,并阅读返回值:
成功时str的内容对应的整数值。如果转换后的值超出相应返回类型的范围,则会发生范围错误,并返回
ULONG_MAX
或ULLONG_MAX
。如果无法执行转换,则会返回0
。
由此我们可以看到,如果您为scanf
"%u"
格式输入的值太大,则结果将ULONG_MAX
转换为unsigned int
。 但是 ,sizeof(unsigned long) > sizeof(unsigned int)
的系统的结果会有所不同。有关此信息,请参见下文。
应该注意的是,在具有64位unsigned long
和32位unsigned int
的平台上,在unsigned long
范围内有效的值将不会转换为例如UINT_MAX
。 4294967299
,而是使用模数算术as detailed here进行转换。
让我们取值unsigned int
。它很大,适合32位unsigned long
,但非常适合64位strtoul
。因此,对ULONG_MAX
的调用不会返回4294967299
,而是返回值unsigned int
。使用标准转换规则(链接到上面),这将导致3
值为{{1}}。