2011-09-12 20 views
0

如果我有一個使用scanf函數獲取用戶輸入數據的程序:用C返回空隙,而不必scanf函數INT

scanf("%d",&val); 

當我通過皮棉運行它,我得到警告說,scanf函數返回一個int和它沒有被分配到任何地方。解決這個問題的實踐是什麼?我是否將它投射爲無效?

(void)scanf("%d",&val); 
+0

'if(!scanf())'? –

+2

這是一個很好的方法。如果你確認結果是'1'(或合適的值),那會更好。 –

+0

@Jeff,同意了。更好地做'if(1 == scanf(「%d」,&val))',因爲它提醒大腦同時修改比較和字符串。 –

回答

4

解決此警告的C最佳實踐很簡單:檢查結果代碼。如果操作沒有問題,則scanf函數返回int值,並將錯誤通常保存在errno中。

缺少結果代碼檢查通常會在某些情況下導致嚴重錯誤。

+1

C最好的做法是避免'scanf'由於許多問題使它強大。 –

0

理想情況下,你會做這樣的事情

int scanVal = scanf("%d", &val); 
if (scanVal != 1) { 
    // wait a minute, scanf couldn't match input to a "%d"! 
} 

,然後以合理的方式輸出行事。

2

當然,正確的答案是不要忽略返回值。對於一個健壯的程序,你應該總是(編輯:通常)檢查返回值是否表示成功,如果沒有則優雅地失敗。

+0

有很多操作,要麼不能失敗,要麼無法優雅地失敗。一個例子是在對它所保護的狀態進行操作後解鎖一個互斥鎖。 「總是檢查失敗」的口頭禪實際上並不奏效;爲了可用,某些功能必須保證它們不會失敗,對於這些功能,不需要檢查返回值。 –

+0

@R ..的確,我不應該說「永遠」,但是scanf絕對不是這些功能之一。 – Chriszuma

+0

如果您使用'%n'來衡量讀取的數量,您可以知道成功/失敗而不檢查返回值。在某些情況下,這可能是一個更好的方法。 –

0

而不是沉默lint消息,只是檢查返回值,以確保沒有任何問題。從手冊頁:

返回值

這些函數返回輸入項數 成功匹配和分配,這可能是 少於所提供,甚至是零在 早期的事件匹配失敗。

如果在 第一次成功轉換或發生匹配失敗之前達到輸入的結尾,則會返回值EOF。如果發生讀取錯誤,EOF也會返回,在這種情況下,會設置流的錯誤指示器(請參閱ferror(3)),並設置 errno指示錯誤。

0

scanf返回成功匹配和分配的輸入項目的數量。將其返回值與您期望的數字進行比較以檢測錯誤。

while (scanf("%d",&val) != 1) 
    printf("Try again.\n"); 
0

使用

#pragma warning(disable:<warning number>) 
scanf("%d",&val); 
#pragma warning(default:<warning number>) 

和你的編譯器將抑制警告。

+0

僅當您的編譯器支持特定的'#pragma'時。 –

0

最佳做法是指定scanf的返回值以查看是否讀取了所有(或多少)項目。在這種特殊情況下,如果它返回1而不是1,那麼出現了問題(例如,你想要一個數字,但用戶給你不可打印的字符),你應該適當地處理它。

0

如果您希望代碼在出現錯誤輸入時保持健壯,請不要使用scanf("%d", ...)

對於大多數錯誤,scanf("%d", &val)將返回0以指示它無法讀取整型值(例如,如果輸入爲「foo」而非「123」)。

但是,如果輸入在語法上有效但超出範圍(例如9999999999999999999),則行爲是未定義

大多數實現可能會表現得很健全,但我不知道它有多少一致性。

要安全地讀取一個int值,使用(未gets()),其次是strtol()fgets()。 (fgets()可能有很長的輸入線問題,但有辦法處理這個問題。)