C ++为什么我重新启动程序时文件会被截断?

时间:2017-04-14 14:24:03

标签: c++ visual-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! ";
}

一切正常,但是一旦我完成程序,即使我试图附加到文件,文件也会擦除并且没有任何内容。为了清楚起见,我需要以前的内容,每次重新打开程序时我都会添加新的行。

3 个答案:

答案 0 :(得分:5)

std::ofstream myFile("SongListFile.txt");打开文件并截断​​。您应该使用std::ofstream myFile("SongListFile.txt", std::ios::app);

否则,您可以使用std::ofstream myFile;声明myFile对象,然后使用它和附加选项打开文件:myFile.open("SongListFile.txt", std::ios::app);

答案 1 :(得分: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打开文件时,文件都会被截断。

答案 2 :(得分:1)

实际上,ofstream构造函数有3个参数:(const char *_Filename, ios_base::openmode _Mode = ios_base::out, int _Prot = (int)ios_base::_Openprot)

所以调用std::ofstream myFile("SongListFile.txt");等于

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"
来自MSDN的

fopen模式描述:

&#34; W&#34; - 打开一个空文件进行写入。如果给定文件存在,则其内容将被销毁。

&#34;&#34; - 在将新数据写入文件之前,打开文件末尾的写入(追加)而不删除文件结束(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!)。