在C中进行基本检查时出现奇怪的数学错误

时间:2013-09-24 04:35:04

标签: c

对于一个简单的程序,分配是创建一个接受十位数电话号码的程序,然后将其读回给用户。 需要进行控制以确保:

  1. 第一个数字不是0.

  2. 输入的数字是十个数字。

  3. 错误检查似乎很简单;我想使用while循环来确保数字的范围在1000000000和9999999999之间,并且根据独立的计算,它似乎应该。

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

    MDNvalueCheck都是long long类型变量(因此范围可以超过2,147,483,647; IIRC long long是64位),但它们似乎仍被列为32位整数,因为输入2147483647就好了(或者任何较低的电话号码都可以正常工作),但输入2,147,483,648(或任何上面的内容)会导致它显示为-2147483647

    与上述相关,输入一个更高的数字,不仅值环绕32位整数的范围,而且循环后printf语句打印的电话号码总是等于输入的数字减去32位整数限制的两倍。

    是否有任何简单的方法可以使程序实际工作在64位数字中,就像我想要的那样?如果我可以使数学运算正常,该算法似乎很可靠。

3 个答案:

答案 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)

问:有没有简单的方法让程序实际工作在64位数字中,就像我想要的那样? 答:使用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