[英]fgetc, checking EOF
在Linux系統編程一書中,我讀過這樣的文章:
fgetc
將讀取的字符作為unsigned char
返回到文件末尾或錯誤的int
或EOF
。 使用fgetc
的常見錯誤是:char c; if ((c = fgetc()) != EOF) {...}
這段代碼的正確版本是:
int c; if ((c = fgetc()) != EOF) { printf("%c", (char)c); ... }
那么,為什么我不能在與EOF
比較之前將返回值轉換為char
? 為什么我必須將EOF
與int
進行精確比較? 當EOF
定義為-1
,它是否通常被轉換為char
?
是否有平台/編譯器不適用?
您不能將返回值強制轉換為char,因為返回值可能是EOF
,並且EOF
值是系統相關的,並且不等於任何有效的字符代碼。 鏈接
通常它是-1
但你不應該假設。
從c-faq網站上查看這個很棒的答案:
如果在上面的片段中,getchar的返回值被賦值給char,則可能出現兩種失敗模式。
如果char類型被簽名,並且如果EOF被定義為(通常)為-1,則帶有十進制值255(C中的'\\ _377'或'\\ xff')的字符將被符號擴展並將比較等於EOF,過早地終止輸入。 (假設8位字符)。
如果char類型是無符號的,則實際的EOF值將被截斷(通過丟棄其高階位,可能導致255或0xff)並且不會被識別為EOF,從而導致無限輸入。
希望能幫助到你!
編輯:(在這個答案中添加@FatalError評論,這在c-faq網站上有解釋,但這對我來說更清楚)
“如果你將它轉換為char,那么EOF與某個有效字符的值相同,因此與該字符無法區分。僅此一點就足以證明不能使結果成為字符”@FatalError注釋。
在與EOF比較之前將值分配給char
時有兩種可能性:
char
是一個有符號的值。 在這種情況下,有一個合法的角色(通常是ÿ,帶有DIAERESIS的小拉丁文字母,U + 00FF)會被誤解為EOF。 char
是無符號值。 在這種情況下,EOF將被轉換為0xFF,然后作為正值提升為int
,它將永遠不會比較等於EOF,這是一個負值。 無論哪種方式,該計划將在某些時候行為不端。
(或者,更確切地說,曾經是)編譯器錯誤的機會,使得分配正確發生但分配的值不用於比較。 這將導致代碼看起來工作正常,即使它不是。 幸運的是,這不太可能是現代編譯器中的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.