[英]Catch errors on stdin, stdout, stderr
我正在寫一些從stdin中讀取的C99代碼:
// [...]
fgets(buf, sizeof(buf), stdin);
// [...]
但是我想知道在這種情況下是否應該捕獲錯誤,因為shell可以將stdin
重定向到可能不如普通stdin
健壯的任何東西。 但這也意味着,必須檢查對stdin
, stdout
和stderr
每次訪問是否有錯誤,而且在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通常是退出循環或退出函數的原因( break
或return
,但是只有在函數未打開文件的情況下才返回;否則,至少必須關閉文件)。 在stdin
上檢測錯誤將很少見。 您將必須決定適合做些什么。
檢測寫到stderr
或stdout
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.