2013-09-24 30 views
1

对于一个简单的程序,该任务是创建一个接受10位电话号码的程序,然后将其读回给用户。 有要控制,以确保:做基本检查时发生奇怪的数学错误C

  1. 第一位数不是0

  2. 即进入人数为10号。

错误检查看起来很简单;我想用一个while循环来确保数字的范围在1000000000和9999999999之间,但根据独立计算,它似乎应该是这样。

while ((MDN - valueCheck < 0) || (MDN > 9999999999)) { 
    printf("Entered number is not ten digits. Please re-enter.\n"); 
    scanf("%d", &MDN); 
} 

两个MDNvalueChecklong long类型变量(使得范围可以晃过2147483647; IIRC长长是64位),但他们似乎仍然被列为32位整数,如进入2147483647 (或者任何较低的电话号码都适用),但输入2,147,483,648(或任何以上)会使其显示为-2147483647

与上述相关的是,输入一个较大的数字,该值不仅包含在32位整数的范围内,而且循环后由printf语句打印的电话号码始终等于输入的数字减去两倍于32位整数的限制。

是否有任何简单的方法使程序实际工作在64位数字中,就像我想要的那样?算法看起来很稳定,如果我可以使数学正常工作。的scanf("%d", &MDN);

从人的scanf

+2

如何变量MDN和valueCheck被填充? – congusbongus

+1

为什么不把电话号码读入字符数组? – Owen

+0

scanf中的“%d”扫描64位整数?我认为这就像“%lld”。如何声明MDN和valueCheck? –

回答

5

尝试scanf("%lld", &MDN);代替:

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). 
0

你可能已经用这样的:

scanf("%lld", &MDN); 

但也有问题与编码方法本身(见下文)
我建议坚持使用字符串正则表达式输入验证方法。

编码问题

scanf()的在一个循环中是易受未处理输入缓冲器问题,例如,如果用户输入文本而不是一个号码 - scanf()的会失败,标准输入不会被消耗,循环将会持续。

有关详细信息,请参阅“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 
+2

%ld会扫描一长整型。 OP有很长的整数。 –

+0

同意 - “%ld”将在32位env下截断它 - 我的错误。稍后将更新这个更有趣的问题的答案。 – Vlad

1

问:有没有什么简单的方法来使程序实际上是64位数字的工作就像我希望它? A:使用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 
+0

'SCN *'宏对我来说是新闻,感谢收藏! –