2013-01-24 85 views
1

有一個文件a.txt中讀取如下:使用的fscanf在項目

1 abc 
2 
3 jkl 

我想讀這個文件的每一行作爲int和一個字符串,像這樣:

fp = fopen("a.txt", "r"); 
while (1) { 
    int num; 
    char str[10]; 
    int ret =fscanf(fp, "%d%s", &num, str); 
    if (EOF == ret) 
     break; 
    else if (2 != ret) 
     continue; 
    // do something with num and str 
} 

但有一個問題,如果a.txt中的一行只包含一個數字,沒有字符串(就像第2行),那麼上面的代碼將被卡在該行。

那麼任何方式跳到下一行?

+0

int ** ret = fscanf(「%d%s」,#num,str)**你忘記了在這個調用中引用fp嗎?它應該是** int ret = fscanf(fp,「%d%s」,#num,str); ** – zdesam

+0

@zdesam,對不起 – Alcott

+0

你有什麼異常? – zdesam

回答

2

做的兩個步驟:

  1. 閱讀使用fgets()全系列。這假定你可以對你想要支持的行數做一個簡單的靜態限制,但是情況往往如此。使用sscanf()來檢查和解析該行。

這可以解決您碰到的問題,並且對於像這樣的問題來說通常是更好的方法。

UPDATE:試圖迴應您的評論。我看到它的方式是,最簡單的方法是始終閱讀整行(如上),然後解析出您認爲它包含的兩個字段:數字和字符串。

如果你這樣做與sscanf(),您可以使用返回值要弄清楚它是如何去,像你fscanf()在你的代碼的嘗試:

const int num_fields = sscanf(line, "%d %s", &num, str); 
if(num_fields == 1) 
    ; /* we got only the number */ 
else if(num_fields == 2) 
    ; /* we got both the number and the string */ 
else 
    ; /* failed to get either */ 

不知道什麼時候你不會「需要」字符串;它可能在那裏,或者不是。

+0

謝謝。如果我在num之後不需要字符串,我的意思是可以使用這個'fscanf(fp,「%u%* c」,&num);'? – Alcott

+0

那麼,我試圖通過使用'fscanf'來完成這項工作一槍,但感謝的人;-) – Alcott

1

如果字符串的第一個字符是\r or\n,這將是一個空字符串。你可以使用比較。 fscanf()函數是不適合的,如果把包含空格的(或空行)。在這種情況下,更好地用fgets()

+0

那麼,問題是,代碼卡在第2行。 – Alcott

1

如何解決「使用的fscanf」:

int後,查找空間(不保存),然後尋找char不在'\n'

int num; 
char str[10]; 
#define ScanInt   "%d" 
#define ScanSpacesDontSave "%*[ ]" 
#define ScanUntilEOL  "%9[^\n]" 

int ret = fscanf(fp, ScanInt ScanSpacesDontSave ScanUntilEOL, &num, str); 
if (EOF == ret) break; 
else if (1 == ret) HandleNum(num); 
else if (2 == ret) HandleNumStr(num, str); 
else HadleMissingNum(); 

ret將2如果東西被掃描到str,否則ret將典型地1.特技上述不以掃描'\n'int之後。因此代碼不能在"%d"之後使用"%s"" ",它們都消耗所有(領先的)空白。 下一個fscanf()通過"%d"作爲主要空白消費的一部分,呼叫將消耗'\n'

小調:讀取fgets(),然後解析緩衝區通常是一個更好的方法,但編碼目標可能會排除這一點。

+0

這很整潔,謝謝。 – Alcott