对于一个简单的程序,分配是创建一个接受十位数电话号码的程序,然后将其读回给用户。 需要进行控制以确保:
第一个数字不是0.
输入的数字是十个数字。
错误检查似乎很简单;我想使用while循环来确保数字的范围在1000000000和9999999999之间,并且根据独立的计算,它似乎应该。
while ((MDN - valueCheck < 0) || (MDN > 9999999999)) {
printf("Entered number is not ten digits. Please re-enter.\n");
scanf("%d", &MDN);
}
MDN
和valueCheck
都是long long
类型变量(因此范围可以超过2,147,483,647; IIRC long long是64位),但它们似乎仍被列为32位整数,因为输入2147483647
就好了(或者任何较低的电话号码都可以正常工作),但输入2,147,483,648(或任何上面的内容)会导致它显示为-2147483647
。
与上述相关,输入一个更高的数字,不仅值环绕32位整数的范围,而且循环后printf
语句打印的电话号码总是等于输入的数字减去32位整数限制的两倍。
是否有任何简单的方法可以使程序实际工作在64位数字中,就像我想要的那样?如果我可以使数学运算正常,该算法似乎很可靠。
答案 0 :(得分:5)
尝试使用scanf("%lld", &MDN);
代替scanf("%d", &MDN);
来自man scanf:
ll (ell ell)
Indicates that the conversion will be one of dioux or n and the
next pointer is a pointer to a long long int (rather than int).
答案 1 :(得分:1)
int64_t
和"%" SCNx64
。
如果你:
想要32位整数,请使用类型int32_t
想要64位整数,请使用类型int64_t
使用int
,范围至少 -32767
至+32767
。
使用long
,范围至少 -2147483647
至+2147483647
。
使用long long
,范围是至少 -9223372036854775807
到+9223372036854775807
。
使用scanf()
使用匹配的格式说明符:
int "%d"
long "%ld"
long long "%lld"
int32_t "%" SCNx32
int64_t "%" SCNx64
答案 2 :(得分:0)
你可以用这个:
scanf("%lld", &MDN);
但编码和方法本身存在问题(见下文)
我建议坚持使用string-regexp输入验证方法。
编码问题:
循环中的scanf()易受 unprocessed-input-buffer问题的影响,例如,如果用户输入文本而不是数字 - scanf()将失败,stdin将不会被消耗,循环将继续永远。
有关详细信息,请参阅“How to clear input buffer in C?”。改变之后应解决它:
while(!scanf("%lld", &MDN)) {
char c;
while(c=getchar()!='\n'&& c!=EOF);
}
接近问题:
该方法本身容易受到溢出和类型修剪问题的影响 例如:“ - 9999999999999999999”将通过所有MDN验证(见下文)。
在将long long(MDN)
与长整数(0或9999999999而不是0LL或9999999999LL)进行比较时,也可能存在编译器/特定问题。
Entered number is not ten digits. Please re-enter.
-9999999999999999999
"MDN" is -9223372036854775808
"MDN > 9999999999" is false
"MDN - valueCheck < 0" is false (!) because "MDN - valueCheck" is 9223372035854775808