簡體   English   中英

如果解析為數字而不是字符串,C fscanf報告EOF

[英]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.

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