[英]C fscanf reports EOF if parsed for a digit but not for a string
我希望將一位數字逐位解析的文件中保留以下文本行:
10001111001000101001010001100000101110000102
但是,當我使用格式說明符%d時,fscanf返回EOF指示符而不是數字。 這與我使用%s的情況形成對比,盡管它一次完成所有操作並以字符串形式返回期望值。
因此,當我更改(以及他從int到char [250]的類型)時,
if (fscanf(f, "%d", &character) != EOF)
至
if (fscanf(f, "%s", &character) != EOF)
如果要逐位掃描,則需要使用"%1d"
作為格式。
否則,它將整行(換行符除外)讀取為數字,並在將大十進制數轉換為32位int
時調用未定義的行為。 請注意,根據普通前綴, d
的助記符不是'數字'而是'十進制',而不是'o'代表八進制,'x'代表十六進制,'i'代表十進制,八進制或十六進制的整數(前導0
代表八進制, 0x
代表十六進制,否則為十進制)。
尚不清楚為什么它返回EOF,但是對於不確定的行為,任何響應都是有效的。
標准(ISO / IEC 9898:2011第7.21.6.2節, fscanf()
函數 ,第10段)指出(在相關部分中):
如果該對象沒有適當的類型,或者無法在對象中表示轉換結果,則該行為是不確定的。
關於錯誤情況下的行為有很多說法,但這是此處的關鍵。 由於行為是不確定的,因此獲得EOF是有效且相對良性的響應。 調查文件流是否處於feof(f)
或ferror(f)
返回true的狀態將很有趣。 沒有明顯的理由應該這樣做,除非您通常不會從fscanf()
獲取EOF,除非其中一個是正確的。
scanf
系列函數中的"%d"
格式說明符將使該函數查找數字序列,該序列以遇到的第一個非數字字符終止。 在您的情況下,使用"%d"
將立即消耗所有數字。
如果"%d"
沒有這樣做,那么您將只能用它讀取一位數字,這幾乎不是任何格式化輸入。
"%s"
格式說明符使字符序列被占用,該字符序列將以空格字符或文件結尾終止。
您在這里尋找的是逐字符讀取輸入的內容。 您可以使用"%c"
格式說明符來實現。 之后,您可以將獲得的字符解釋為數字值。
例如; 您可以讀取第一個'1'
字符,然后從中減去'0'
字符,這將產生'1' - '0' == 1
,這就是您想要的東西。
fscanf
返回失敗時分配的輸入項目數或EOF
。 那只是一個問題。 另一個是它將繼續使用輸入字符串中的字符,直到遇到\\0
字符或非數字(在%d
情況下)為止。 傳遞單個字符的地址也不是一件有效的事情。 您可以改為執行以下操作:
char *p;
for (p=&input_string[0]; isdigit(*p); p++) {
int digit = (int)(*p - '0');
/* process digit */
}
如果要使用scanf
函數之一,請創建一個包含兩個字符的字符串-正在處理的數字和\\0
。 然后sscanf
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.