2012-06-29 50 views
2

我想寫一些簡單的代碼,它將讀取文本文件,但讀取第一行兩次。我認爲這會像這樣簡單seekg()函數失敗

std::ifstream file; 
    file.open("filename", std::ios_base::in); 
    std::string line; 
    std::getline(file, line); 
    // process line 
    file.seekg(0, ios::beg); 

    while (std::getline(file, line)) 
    { 
     // process line 
    } 

但是,由於第一行不會被處理兩次,seekg必須失敗。任何想法爲什麼?

請注意:這不是我所面臨的問題,但它以免必須粘貼多個類別代碼和多種功能的簡化版本。真正的問題涉及將文件指針傳遞給多個類中的多個函數。第一個函數可能調用也可能不調用,並讀取文件的第一行。第二個函數讀取整個文件,但必須先調用seekg以確保我們處於文件的開頭。

我只是用上面的代碼以簡化討論。

+3

第一'的std :: getline'呼叫可能設置EOF標誌。 – ildjarn

+1

@ildjarn它確實,但它不是問題。 'seekg'在它做任何事之前清除eof標誌。 'char *'的'getline'有時會設置'failbit',而不是'std :: string'超載。此外,我驗證了這個問題...... – Potatoswatter

+0

@Potatoswatter:「*'seekg'在它做任何事情之前清除了eof標誌*」我沒有意識到這一點,謝謝。 : - ] – ildjarn

回答

3

而不是尋求回到起點和閱讀的第一行兩次,我想我會做法事的東西,如:

std::ifstream file("filename"); 

std::string line; 

std::getline(file, line); 
process(line); 

do { 
    process(line); 
} while (getline(file, line)); 

目前,這個假設process不修改line(但如果需要的話,很容易足以讓它第一次調用的額外副本)。

編輯:給出的答案編輯修改的要求,它聽起來就像是尋求真正需要的。既然如此,它可能是乾淨的,然後再繼續clear流:

std::getline(file, line); 
process1(line); 

file.seekg(0); 
file.clear(); 

process2(file); 
+1

不,我不能那樣做。我極大地簡化了代碼,以免拖出更復雜的過程。實際上,文件指針正被傳遞給不同的函數。一個函數只能讀取文件的第一行。另一個函數必須從文件的開頭再次讀取,並且不知道第一個函數是否執行,因爲它是可選階段。我不想粘貼大量的代碼,只是簡化了上面的代碼的問題。 – Jonnster

+2

在這種情況下,您應該編輯問題以反映您的真實需求,而不是降低有效答案。 –

+0

公平點。編輯答案,我可以重新點擊。 – Jonnster

2

理想的情況下你的代碼應該是這樣的:

std::ifstream file("filename"); //no need of std::ios_base::in 

if (file) //check if the file opened for reading, successfully 
{ 
    std::string line; 
    if (!std::getline(file, line)) 
    { 
     std::cerr << "read error" << std::endl; 
     return; 
    } 

    // process line 

    if (!file.seekg(0, ios::beg)) 
    { 
     std::cerr << "seek error" << std::endl; 
     return; 
    } 

    while (std::getline(file, line)) 
    { 
     // process line 
    } 
} 
else 
{ 
    std::cerr << "open error" << std::endl; 
} 
+0

寫了一個測試程序......它不報告任何狀態位被設置。 – Potatoswatter

+0

@Patatoswatter:那麼,正如你所說的那樣,它是庫中的一個錯誤,我的回答只是簡單地說明了代碼應該是什麼樣子,理想情況。 – Nawaz

+1

是的,你的代碼是典範。我只是提到這種情況下的輸出。 – Potatoswatter