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

Scanning a number having more data than predefined value

#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的情况下循环?

来自 this scanf (and family) reference "%u" 格式:

The format of the number is the same as expected by strtoul() with the value ​0​ for the base argument (base is determined by the first characters parsed)

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

Integer value corresponding to the contents of str on success. If the converted value falls out of range of corresponding return type, range error occurs and ULONG_MAX or ULLONG_MAX is returned. If no conversion can be performed, ​0​ is returned.

由此可见,如果scanf "%u"格式输入的值过大,那么结果会ULONG_MAX转换为unsigned int但是 结果在 sizeof(unsigned long) > sizeof(unsigned int) 的系统上会有所不同。有关这方面的信息,请参阅下文。


需要注意的是,在64位unsigned long和32位unsigned int的平台上,unsigned long范围内有效的值不会被转换为例如UINT_MAX,而是使用模运算 as detailed here.

进行转换

让我们取 4294967299 这样的值。它对于 32 位 unsigned int 来说太大了,但是对于 64 位 unsigned long 来说却非常适合。因此对 strtoul 的调用不会 return ULONG_MAX,而是 4294967299 的值。使用标准转换规则(链接到上面),这将导致 unsigned int 值为 3

C11 标准草案 n1570 7.21.6.2 说如下

paragraph 10

[...] the input item [...] is converted to a type appropriate to the conversion specifier. If the input item is not a matching sequence, the execution of the directive fails: this condition is a matching failure. Unless assignment suppression was indicated by a *, the result of the conversion is placed in the object pointed to by the first argument following the format argument that has not already received a conversion result. If this object does not have an appropriate type, or if the result of the conversion cannot be represented in the object, the behavior is undefined.

这里"conversion"这个词是用来进行字符串=>结果数据类型转换的,不能理解为整数转换。由于转换为十进制整数的字符串 "4294967299" 在 32 位宽的 unsigned int 类型的对象中不可表示,因此标准的阅读表明行为未定义,即

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

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

ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message).