1

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

  1. 第一个数字不是 0。

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

错误检查似乎很简单;我认为使用 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循环后语句打印的电话号码总是等于输入的数字减去 a 限制的两倍32 位整数。

有没有什么简单的方法可以让程序像我想要的那样在 64 位数字中实际运行?如果我能让数学正常工作,该算法似乎很可靠。

4

3 回答 3

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).
于 2013-09-24T04:42:40.310 回答
1

问:有没有什么简单的方法可以让程序像我想要的那样在 64 位数字中实际运行?
答:使用int64_t"%" SCNx64

如果您:
想要 32 位整数,请使用 type int32_t
想要 64 位整数,请使用 type 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  
于 2013-09-24T13:38:56.990 回答
0

你可以用这个:

scanf("%lld", &MDN);

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

编码问题

循环中的 scanf() 容易受到未处理输入缓冲区问题的影响,例如,如果用户输入文本而不是数字 - scanf() 将失败,标准输入将不会被消耗,并且循环将永远继续。

有关详细信息,请参阅“如何在 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
于 2013-09-24T05:07:27.420 回答