扫描数据多于预定义值的数字

时间:2015-09-18 09:20:08

标签: c scanf

#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的情况下会关注?

2 个答案:

答案 0 :(得分:6)

C11标准草案n1570 7.21.6.2说明如下

paragraph 10

  

[...]输入项[...]转换为适合转换说明符的类型。如果输入项不是匹配序列,则指令的执行失败:此条件是匹配失败。除非*指示赋值抑制,否则转换的结果将放在由尚未收到转换结果的format参数后面的第一个参数指向的对象中。如果此对象没有合适的类型,或者无法在对象中表示转换结果,则行为未定义

现在,&#34;转换&#34;这里用于string =&gt;结果数据类型转换,不能理解为整数转换。由于转换为十进制整数的字符串"4294967299"在32位宽的unsigned int类型的对象中无法表示,因此标准的读取表明行为未定义,即

  使用不可移植或错误的程序结构或错误数据的行为,本国际标准没有规定

因此,您的问题的答案是C标准在这种情况下没有说明行为,您看到的行为是您的编译器和C库实现的行为,并且不可移植;在其他平台上,可能的行为可能包括:

  

完全忽略不可预测的结果的情况,在翻译或程序执行过程中以文档化的方式表现环境(有或没有发出诊断消息),终止翻译或执行(发布诊断消息)。

答案 1 :(得分:-4)

this scanf (and family) reference格式为"%u"

  

数字的格式与strtoul()的预期相同,基本参数的值为​0​(基数由解析的第一个字符决定)

然后我们转到strtoul函数,并阅读返回值:

  

成功时str的内容对应的整数值。如果转换后的值超出相应返回类型的范围,则会发生范围错误,并返回ULONG_MAXULLONG_MAX。如果无法执行转换,则会返回​0

由此我们可以看到,如果您为scanf "%u"格式输入的值太大,则结果将ULONG_MAX转换为unsigned int 但是 sizeof(unsigned long) > sizeof(unsigned int)的系统的结果会有所不同。有关此信息,请参见下文。

应该注意的是,在具有64位unsigned long和32位unsigned int的平台上,在unsigned long范围内有效的值将不会转换为例如UINT_MAX4294967299,而是使用模数算术as detailed here进行转换。

让我们取值unsigned int。它很大,适合32位unsigned long,但非常适合64位strtoul。因此,对ULONG_MAX的调用不会返回4294967299,而是返回值unsigned int。使用标准转换规则(链接到上面),这将导致3值为{{1}}。