簡體   English   中英

在stdin,stdout,stderr上捕獲錯誤

[英]Catch errors on stdin, stdout, stderr

我正在寫一些從stdin中讀取的C99代碼:

// [...]
fgets(buf, sizeof(buf), stdin);
// [...]

但是我想知道在這種情況下是否應該捕獲錯誤,因為shell可以將stdin重定向到可能不如普通stdin健壯的任何東西。 但這也意味着,必須檢查對stdinstdoutstderr每次訪問是否有錯誤,而且在printf和co之后我很少看到任何檢查。

因此,是否建議檢查每個流訪問是否有錯誤?

上面的示例將是這樣的:

// [...]
if (!fgets(buf, sizeof(buf), stdin) && ferror(stdin)) {
    exit(EXIT_FAILURE);
}
// [...]

提前致謝!

每次使用它時,您始終必須檢查fgets()的返回值。 如果不這樣做,則不知道緩沖區中是否有有用的數據。 它可以第二次保持最后一行。 類似的注釋適用於每個讀取操作。 您必須檢查讀取操作是否返回了預期的結果。

if (fgets(buf, sizeof(buf), stdin) == 0)
    ...EOF, or some error...

在處理代碼中,您需要決定要做什么。 您可以在該代碼中合法使用feof()ferror() 對問題的正確反應取決於您的代碼。 檢測EOF通常是退出循環或退出函數的原因( breakreturn ,但是只有在函數未打開文件的情況下才返回;否則,至少必須關閉文件)。 stdin上檢測錯誤將很少見。 您將必須決定適合做些什么。

檢測寫到stderrstdout stderr不是很常見,但是可以忽略掉它們是很松懈的編程。 一個問題(尤其是如果stderr出了問題)是“您將如何報告該錯誤?” 您可能需要改用syslog() ,但這是您必須考慮的問題。

這取決於您正在開發的應用程序的性質。 例如,如果您正在開發硬實時系統,其異常終止會導致嚴重問題。 那么您應該采取預防措施來處理各種數據流錯誤。 在這種情況下,請使用以下代碼,

if (!fgets(buf, sizeof(buf), stdin) && ferror(stdin)) {
    exit(EXIT_FAILURE);
}

或類似的結構。 但是,如果應用程序的罕見故障不會造成任何嚴重后果,則無需檢查每個數據流操作。

這是一個有趣的練習。 找到某人的交互式程序,運行該程序,直到從終端要求輸入,然后按Control-D(EOF)。 可能是作者沒有檢查feof(stdin),而他的gets()調用僅返回0字節,該代碼將其解釋為空白行。 如果將其視為無效輸入並再次提示,則將陷入無限循環!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM