2010-02-21 77 views
2

考慮下面的C++程序,它接收一個文件並打印每一行。根據我所看到的,這是我稍後追加到該文件的較大程序的一部分。爲什麼我不能在Mac OS X上讀取和追加std :: fstream?

#include <fstream> 
using std::fstream; 
#include <iostream> 
#include <string> 
using std::string; 

int main() 
{ 
fstream file("file.txt", fstream::in | fstream::out | fstream::app); 

string line; 
while (std::getline(file, line)) 
    std::cerr << line << std::endl; 

return 0; 
} 

立即應用此版本file.txt的(第一行一個單詞,跟着一個換行符):

Rain 

在我的機器(雪豹),這個打印出什麼。經仔細檢查,第一次調用getline失敗。奇怪的是,如果我添加第二行,它也會失敗:仍然沒有打印!

誰能解開這個謎?

+0

你的程序爲我工作,所以它可能是在您的環境中的錯誤。你有沒有嘗試開放只讀,即只是'fstream :: in'? – 2010-02-21 09:53:54

+0

在這裏也能正常工作,就像Earwicker說的那樣,並檢查你的文件是否真的被打開。 – Manuel 2010-02-21 09:56:32

+0

順便說一句,你正在發送文本到'std :: cerr' - 'std :: cout'對於實際輸出會更加正常。 'std :: cerr'用於錯誤報告(正如我的答案中)。 – 2010-02-21 10:01:21

回答

9

當你說:

fstream file("file.txt", fstream::in | fstream::out | fstream::app); 

你追加模式打開文件 - 即在最後。只是在讀模式下打開它:

fstream file("file.txt", fstream::in); 

或使用ifstream的:

ifstream file("file.txt"); 

當然,正如埃裏克建議,你應該總是測試打開成功。

如果你有決心在追加模式打開,你可以明確地移動讀指針:

#include <fstream> 
#include <iostream> 
#include <string> 
using namespace std; 

int main() { 
    fstream file("afile.txt", ios::in | ios::out | ios::app); 
    if (! file.is_open() ) { 
     cerr << "open failed" << endl; 
     return 1; 
    } 
    else { 
     file.seekg(0, ios::beg); // move read pointer 
     string line; 
     while(getline(file, line)) { 
      cout << line << endl; 
     } 
    } 
} 

編輯:看來,在打開文件所使用的標誌的組合導致實施具體行爲。上面的代碼適用於Windows上的g ++,但不適用於Linux上的g ++。

+0

但是不是獨立於寫入位置的讀取位置? – 2010-02-21 10:03:31

+0

顯然不是 - 這是正確的答案。那些表示他們在自己的系統上嘗試過的人可能已經弄髒了! :) – 2010-02-21 10:05:49

+0

@埃裏克 - 這是一個強烈的指責,並且可悲的是你完全沒有理由。並認爲我upvoted你的答案... – Manuel 2010-02-21 10:13:42

2

你應該檢查文件是否實際上已被打開:

if (!file) 
    std::cerr << "Oh dear" << std::endl; 

更新:事實上該文件可能已經打開,但在附加模式 - 見Neii的答案。

更新2:沒關係,錯了。在Leopard中的G ++至少,該文件將不會打開,因爲app標誌和in標誌不兼容。所以上面的檢查將打印Oh dear

在MSVC++,它會開始打開該文件,顯然在開始讀取位置,這也解釋了爲什麼其他人看到它的工作和我的懷疑他們的真實性道歉!

相關問題