2013-09-24 36 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 *'宏對我來說是新聞,感謝收藏! –