2010-03-29 45 views
11

什麼是最好的選擇,如果我想讀取文件用分號分隔符時,「升級」舊的C代碼,以新的C++:舊式(C-like)fscanf方法的現代等效(C++)風格是什麼?

/* reading in from file C-like: */ 
fscanf(tFile, "%d", &mypost.nr); /*delimiter ; */ 
fscanf(tFile, " ;%[^;];", mypost.aftername);/* delimiter ; */ 
fscanf(tFile, " %[^;]", mypost.forename); /*delimiter ; */ 
fscanf(tFile, " ;%[^;];", mypost.dept);/*delimiter ; */ 
fscanf(tFile, " %[^;];", mypost.position);/* delimiter ; */ 
fscanf(tFile, "%d", &mypost.nr2); 

//eqivalent best C++ method achieving the same thing? 
+0

我想知道fscanf有多嚴格?如果你用帶有forename的行讀取所有字符,那麼下一行如何在分號之前讀取一個空格? - 另外,如果你還可以指定要讀取的最大字符數,'fscanf'可能不會那麼糟糕。 – UncleBens 2010-03-29 15:49:12

回答

11

您可以重載在istream的右移位運算符爲你的結構,所以:

std::istream& operator>>(std::istream& is, mypost_struct& mps) { 
    is >> mps.nr; 
    is.ignore(1, ';'); 
    is.getline(mps.forename, 255, ';'); 
    is.getline(mps.aftername, 255, ';'); 
    is >> mps.dept; 
    is.ignore(1, ';'); 
    is >> mps.position; 
    is.ignore(1, ';'); 
    is >> mps.nr2; 

    return is; 
} 

隨後,輸入是is >> mypost;,其中is是你打開文件一樣簡單。

編輯:@UncleBens感謝您指出這一點,我忘記了佔空間。我已經更新了答案,假設forename和aftername可能包含空格。還有是關於分隔符是雙引號的這個相當尷尬有點...

我只是檢查它使用結構定義爲下:

struct mypost_struct { 
    int nr; 
    char forename[255], aftername[255]; 
    int dept, position, nr2; 
}; 

...,結果是如預期。

+0

我想知道所有upvotes是什麼。提供重載'>>'的想法很好,但實現(**如何讀取分隔的輸入)完全被破壞。 'ignore'沒有這種形式,即使你修復它,這也不會改變'istream.operator >>'的行爲,並使用「;」作爲分隔符。如果輸入也用空格分隔,並且沒有任何字符串包含多於一個單詞,那麼它會進行排序。 – UncleBens 2010-03-29 14:56:58

+0

感謝您指出這:) – susmits 2010-03-29 17:39:25

3

由於@susmits說,但你也可以使用返回流作爲一個條件,如:

if (is >> mps.nr && is.ignore(1, ";") && is >> mps.aftername && ...) { 
    // all is well ... 
} else { 
    // bad input format 
} 

甚至:

if (is >> mps.nr >> ignore(";") >> mps.aftername >> ...) { 
    // all is well ... 
} else { 
    // bad input format 
} 
1

什麼是最好的選擇,如果我想到 將舊的C代碼「升級」到更新的C++ ...?

恕我直言,最好的辦法是逐行讀取文件並使用regular expressions for parsing

相關問題