2017-04-14 60 views
2

我試圖用這段代碼從文件中讀取數據並將其存儲在向量中。這工作一次並正確顯示一切。C++爲什麼我的文件在我重新啓動程序時被截斷?

void SongList::LoadSongsFromFile() 
{ 
    song temp; 
    string line; 
    ifstream myFile("SongListFile.txt"); 
    while (getline(myFile, line)) { 
     myFile >> temp.title; 
     myFile >> temp.artist; 
     myFile >> temp.genre; 
     songs.push_back(temp); 
    } 
} 

我再要附加到文件,使用以下:

void SongList::AddSong(song tmp) 
{ 
    cout << "Enter the title, artist then genre of the song, each on a new line.\n"; 
    cin >> tmp.title; 
    cin >> tmp.artist; 
    cin >> tmp.genre; 
    songs.push_back(tmp); 
    ofstream myFile("SongListFile.txt"); 
    myFile.open("SongListFile.txt", ios::app); 
    myFile << tmp.title << " " << tmp.artist << " " << tmp.genre; 
    cout << tmp.title << " by " << tmp.artist << " is now a part of the song library! "; 
} 

一切工作正常,但即使該文件將擦拭,並沒有任何在它一旦我完成這個項目,我試圖追加到該文件。爲了清楚起見,我需要以前的內容,並且每次重新打開程序時添加的新行都在那裏。

+0

myFile.flush(); – KonstantinL

+1

@KonstantinL'ofstream'關閉破壞並關閉時刷新。 –

+0

擦除整個文件並沒有什麼意義。考慮一下你可能正在查看錯誤的文件,當你不使用完整路徑名並依賴於默認工作目錄時,這是一個長期的問題。 –

回答

5

std::ofstream myFile("SongListFile.txt");打開文件並截斷​​。您應該使用std::ofstream myFile("SongListFile.txt", std::ios::app);

否則,你可以聲明MYFILE對象與std::ofstream myFile;,然後用它和附加選項打開文件:myFile.open("SongListFile.txt", std::ios::app);

+0

這工作,謝謝。我有一種感覺,這是與myFile.open函數有關。 – drewpy

+0

這是真的,但有點奇怪,因爲std :: ios :: trunc和std :: ios:out(默認arg)似乎沒有區別。 – KonstantinL

+1

@drewpy:從現在開始養成閱讀documentation_的習慣。猜測編程不起作用。 –

3

更換

ofstream myFile("SongListFile.txt"); 
myFile.open("SongListFile.txt", ios::app); 

ofstream myFile("SongListFile.txt",ios::app); 

ofstream myFile; 
myFile.open("SongListFile.txt", ios::app); 

什麼在你的代碼情況是,ofstream myFile("SongListFile.txt")打開默認模式ios::out文件,然後在下一行打開文件與myFile.open("SongListFile.txt", ios::app);的嘗試,因爲該文件已經被先前的線使得ios::app無效的打開失敗該文件,因此每次使用ofstream打開文件時,文件都會被截斷。

1

實際上,流構造函數有3個參數:(const char *_Filename, ios_base::openmode _Mode = ios_base::out, int _Prot = (int)ios_base::_Openprot)

所以通話std::ofstream myFile("SongListFile.txt");被equavalent到

std::ofstream myFile("SongListFile.txt", std::ios::out);

備註:std::ios::out == ios_base::out。作爲第二個參數

其它可能的值包括:

std::ios::app 
std::ios::trunc 
在CRT代碼

更深該參數根據該第一翻譯:

std::ios::out --> std::ios::out 
std::ios::trunc --> std::ios::trunc | std::ios::out 
std::ios::app --> std::ios::app | std::ios::out 

而更深一點它被翻譯成良好舊fopen模式按此:

std::ios::out --> "w" 
std::ios::trunc | std::ios::out --> "w" 
std::ios::app | std::ios::out --> "a" 

fopen來自MSDN的模式說明:

「w」 - 打開一個空文件進行寫入。如果給定文件存在,其內容將被銷燬。

「a」 - 在將新數據寫入文件之前,在文件末尾(追加)打開而不刪除文件結束(EOF)標記。如果該文件不存在,則創建該文件。

TL; DR:

std::ofstream myFile("SongListFile.txt"); - 重設文件的內容。

std::ofstream myFile("SongListFile.txt", std::ios::out); - 重置文件內容。

std::ofstream myFile("SongListFile.txt", std::ios::trunc); - 重置文件內容。

std::ofstream myFile("SongListFile.txt", std::ios::app); - 不要重置文件內容。

前3個變體是等效的(對於std :: ofstream!)。

+1

到目前爲止,這給出了最佳解釋開放模式如何工作。可以添加[鏈接到文檔](http://en.cppreference.com/w/cpp/io/basic_filebuf/open)。 – zett42

相關問題