當我寫這一點,編譯和運行:scanf失敗爲什麼?
int x;
scanf ("%d", &x);
while (x!=4) {
scanf ("%d", &x);
}
和插入字符或雙號小於4時進入無限循環。
當插入雙倍大於4時,它終止。
任何解釋?
當我寫這一點,編譯和運行:scanf失敗爲什麼?
int x;
scanf ("%d", &x);
while (x!=4) {
scanf ("%d", &x);
}
和插入字符或雙號小於4時進入無限循環。
當插入雙倍大於4時,它終止。
任何解釋?
7.19.6.2 fscanf函數
...
4 fscanf函數依次執行格式的每個指令。如果指令失敗,如下所述,函數返回。故障被描述爲輸入故障(由於出現編碼錯誤或輸入字符不可用)或匹配故障(由於輸入不正確)。
...
7作爲轉換規範的指令定義了一組匹配的輸入序列,如下面每個說明符所述。 A轉換規範在下面的步驟執行:
8輸入的空白字符(由isspace爲函數指定)被跳過,除非 說明書包括 [, Ç,或 Ñ說明符。 250)
9的輸入項目是從該流讀取,除非本說明書中包括 Ñ說明符。輸入項被定義爲輸入字符的最長序列,其不超過任何指定的字段寬度,並且是匹配輸入序列的或者是匹配輸入序列的前綴。 251)輸入項目保持未讀狀態後的第一個字符(如果有的話)。如果輸入項目的長度爲零,則指令的執行失敗;除非文件結束,編碼錯誤或讀取錯誤阻止了來自流的輸入,否則此條件是匹配失敗,在這種情況下,這是輸入失敗。
10除了在 %說明符時,輸入項(或者,在一個 %N指令,輸入字符的計數的情況下)的情況下被轉換成適合於該轉換指定一個類型。 如果輸入項目不是匹配序列,則指令的執行將失敗:此條件是匹配失敗。除非通過*指定了分配抑制,否則轉換結果將放置在尚未收到轉換結果的format參數之後的第一個參數指向的對象中。如果此對象沒有適當的類型,或者轉換的結果不能在對象中表示,則行爲是未定義的。
第10段中增加了重點。%d
轉換說明符預計將輸入文本格式化爲十進制整數。如果不是,則轉換將失敗,導致轉換失敗的字符將保留在輸入流中。對scanf()
與%d
轉換說明符的進一步調用將扼殺在同一個字符上。
scanf()
返回成功分配的數量;你需要檢查這個結果,看看是否轉換成功,就像這樣:
int x = 0;
while (x != 4)
{
int result = scanf("%d", &x);
if (result != 1)
{
printf("Last call to scanf() failed; exiting\n");
break;
}
}
不幸的是,你仍然有錯誤的輸入卡的輸入流。有很多處理這個問題的策略。你可以用getchar
刪除有問題的字符,然後再試一次:
while (x != 4)
{
int tmp;
if (scanf("%d", &tmp) == 0)
getchar();
else
x = tmp;
}
或者你可以嘗試讀取到下一個新行,假設所有剩餘輸入b0rked:
while (x != 4)
{
int tmp;
if (scanf("%d", &tmp) == 0)
while (getchar() != '\n')
;
else
x = tmp;
}
或者你可以嘗試讀取輸入作爲文本和轉換使用strtol()
(我的優選技術)爲整數:
char input[SOME_SIZE];
int x = 0;
...
while (x != 4)
{
if (fgets(input, sizeof input, stdin))
{
char *check;
int tmp = (int) strtol(input, &check, 10);
if (!isspace(*check) && *check != 0)
{
printf("%s is not a valid integer: try again\n", input);
}
else
{
x = tmp;
}
}
else
{
printf("Read error on standard input\n");
break;
}
}
這是更多的工作,但它可以讓你在之前捕獲不好的輸入,它被分配到x
。
您傳遞給scanf的%d告訴它解析一個int。當你輸入一個double時,它不能解析既不將分析數據存儲在x變量中,因爲double在32位機器上使用64位而在32位上使用int,從而產生了一個Seg。故障或隨機附帶影響。
-1 scanf讀取** text **。如果你輸入一個小數點(或一個指數,或任何*錯誤*的東西),scanf因不適當的字符而停止。 – pmg 2010-10-25 15:40:48
當scanf函數在輸入流中的特定位置停止掃描,它永遠不會提前流,所以下一個scanf函數會再試一次同樣的錯誤......又一次......又一次
input: 42 23 foo ... scanf:^ x 42 scanf: ^ x 23 scanf: ^ x unusable scanf: ^ x unusable scanf: ^ x unusable scanf: ^ x unusable scanf: ^ x unusable
如何,如果我輸入一個雙數小於4它進入一個無限循環。當插入雙倍大於4時終止。 – Aboelnour 2010-10-25 15:43:00
我無法解釋這種行爲。當x不是4時循環停止。但是,在失敗的scanf後使用x是Undefined Behavior:任何事情都可能發生。 – pmg 2010-10-25 15:47:27
@Aboelnour如果你輸入'4.29419541951',它會讀取'4'作爲一個整數並退出。如果輸入'3.29419541951',它將讀取'3',然後在下一個循環中失敗,因爲第一個字符是'.'。你需要檢查返回值。檢查我的答案中的代碼。 – 2010-10-25 15:51:28
投票的參考和getchar()解決方案 – Aboelnour 2010-10-25 19:37:05
只是一個小小的評論。忽略部分輸入實際上是一種非常糟糕的做法。你應該首先報告出現問題的錯誤,而不要繼續閱讀。 – 2010-10-25 19:45:10