2014-10-27 65 views
2

的問題是以下內容:fscanf無法檢測到匹配失敗。 libc錯誤或不?


#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    float f = 0.0f; 
    int n = 0; 

    n = fscanf(stdin, "%f", &f); 
    printf("n = %d, f = %f\n", n, f); 

    return 0; 
} 

它打印:

n = 1時,F = 100.0000

如果輸入字符串是:

100ergs

已經提供給stdin。以下行爲在gcc(4.8.1)和VS2010(及更低版本)上發生。這是一個錯誤,還是我錯過了什麼?由於7.19.6.2.19和7.19.6.2.20節中的c標準(c89)明確指出,由於匹配失敗,n應該等於零。

UPD。只是一些額外信息:

http://port70.net/~nsz/c/c99/n1256.html#7.19.6.2p20(Thx至克里斯翹用於鏈路)

2)用於匹配失敗,其如預期運作類似的例子:

#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int hex = 0x0; 
    int n = 0; 

    n = fscanf(stdin, "%x", &hex); 
    printf("n = %d, hexVal = %x\n", n, hex); 

    return 0; 
} 

1)從標準的例子

如果stdin包含0xz輸出爲

n = 0,hexVal = 0

+1

這不是一個匹配失敗。匹配在遇到'e'並且'ergs'未被解析時停止。如果你需要更好的控制,可以考慮使用'strtod',這當然意味着你必須先從'stdin'中讀取一個字符串。 – 2014-10-27 07:26:25

+2

好的,但上面各節中的標準明確指出,在這種情況下(這個例子中輸入相同的例子),它是一個匹配失敗。這就是讓我困惑的原因...... – HighPredator 2014-10-27 07:33:38

+2

@HighPredator,我不想編輯太多的問題,但是您可能想從C99草稿的7.19.6.2.20引用並鏈接到http://port70.net/ 〜nsz/c/c99/n1256.html#7.19.6.2p20作證明。行'count = 0; //「100e」不能匹配「%f」'很重要。 – 2014-10-27 07:38:48

回答

1

除非他們對最終標準進行了修改,否則您看到的行爲就是一個錯誤。 (感謝HighPredator的鏈接)

Difference between scanf() and strtol()/strtod() in parsing numbers

+0

這是一件新鮮事。我從未在任何地方見過。你能提供一個鏈接嗎?因爲我的印象是,scanf組和strto ..組在機械上是不同的功能。 – HighPredator 2014-10-27 08:45:39

+0

是的,顯然他們的確在機械上有所不同。 http://stackoverflow.com/questions/1425730/difference-between-scanf-and-strtol-strtod-in-parsing-numbers – HighPredator 2014-10-27 08:47:58

+0

@HighPredator我誤讀了鏈接的草稿。它似乎是一個錯誤。感謝您指出。 – 2014-10-27 09:00:04

0

您正在閱讀的是流。 fscanf獲取所有可接受的字符...並將其餘部分留給下一次讀取操作。在C語言中,以下兩個片段給出了相同的結果:

int i, j; 
fscanf(stdin, "%d", &i); 
fscanf(stdin, "%d", &j); 

int i, j; 
fscanf(stdin, "%d%d", &i, &j); 

,如果你有1 2喂,你會得到i=1j=2

,你會從該期待什麼:

float f = 0.0f; 
int n = 0; 
char c[16]; 

n = fscanf(stdin, "%f", &f); 
printf("n = %d, f = %f\n", n, f); 
n = fscanf(stdin, "%15s", c); 
printf("n = %d, string = %s\n", n, c); 

當用100erg你:

n = 1, f = 100.0000 
n = 1, string = erg 

所以當前fscanf結果是完全正確的,因爲100是作爲輸入浮動可以接受的。

+0

這就是我想指出的。 「所以目前的fscanf結果是完全正確的。」這不是,就上面的標準例子而言。其次,根據6.4.4.2的描述,100erg的100e部分是一個有效的「前綴」。由於這個標準,在這種情況下,標準要求scanf返回零。 – HighPredator 2014-10-27 10:22:15

+0

看起來像我的段落的計數不同於這個...無論如何,這就是我在說的http://port70.net/~nsz/c/c89/c89-draft.html#3.1.3.1 – HighPredator 2014-10-27 10:23:48

+0

簡而言之,我看到它的方式:100e是指數形式的浮點值的有效「前綴」(就像十六進制的0x一樣),那麼在它之後,stdin不包含有效的數字部分。在這種情況下,應該發生匹配失敗的情況(就像十六進制一樣),應該返回零。 – HighPredator 2014-10-27 10:27:35

相關問題