写入文件会导致空文件

时间:2014-11-05 12:10:37

标签: c++ file-io

我写了一个小程序,它打开一个文件,从文件中的每一行构建一个向量,然后让用户能够从文件中添加/删除。程序首先从向量中删除,然后根据向量重建文件。这里是重建文件的代码(fileName是一个带有文本文件全名的成员变量,例如" test.txt":

bool rebuildFile() {
    if (remove(fileName.c_str()) == 0) {    // remove the old file
        ofstream newFile(fileName);         // create new file with same name
        newFile.open(fileName, ios::app);   // open to append to end of file
        if (newFile.is_open()) {            
            newFile << fileHeader << endl;  // add the first header line
            for (int i = 0; i < myVector.size(); i++) {  // loop through vector, adding strings to file
                newFile << myVector[i] << endl;   // I used "\n" instead of endl, but both give same results
            }
            newFile.close();
            return true;     // success
        }
    }
    return false;            // failure
}

退出此功能后,文件完全为空。所以它清楚地创建了一个新文件,但是写作部分是一个问题,我无法弄清楚原因。我读过其他一些帖子,其中有些问题是他们在Notepad / Notepad ++中打开了文件,但我总是确保在运行程序之前关闭该特定文件。我不确定ios :: app标志是否会导致循环出现问题,但是文档似乎很清楚它只是指向每次输出文件时文件的结尾,所以我没有&#39;我认为这个问题存在。有什么想法吗?

编辑:

显然你无法附加到一个空文件......这个新代码有效,但我不确定是否有一个&#34;更清洁的&#34;以两种不同的方式添加到文件的方式,而不使用不同的标志打开和关闭它两次。

新代码:

bool rebuildFile() {
    if (remove(fileName.c_str()) == 0) {
        std::ofstream newFile(fileName);
        newFile.open(fileName);
        if (newFile.is_open()) {
            newFile << fileHeader << endl;
            newFile.close();
        }
        newFile.open(fileName, std::ofstream::out | std::ofstream::app);
        if (newFile.is_open()) {
            for (int i = 0; i < myVector.size(); i++) {
                newFile << myVector[i] << endl;
            }
            newFile.close();
            return true;
        }
    }
    return false;
}

2 个答案:

答案 0 :(得分:3)

尝试在已打开的文件流上调用open会使流处于失败状态。

只需更改

ofstream newFile(fileName);         // create new file with same name
    newFile.open(fileName, ios::app); 

ofstream newFile(fileName, ios::app); 

[ofstream.members]

  

void open(const char* s, ios_base::openmode mode = ios_base::out);

     

效果:致电rdbuf()->open(s, mode | ios_base::out)。如果说   函数不返回空指针调用clear()否则调用   setstate(failbit) (可能会抛出ios_base::failure(27.5.5.4))。

[fi lebuf.members]

  

basic_filebuf<charT,traits>* open(const char* s, ios_base::openmode mode);

     

效果:如果is_open() != false返回空指针。 [...]

     

bool is_open() const;

     

返回:如果先前对open的调用成功,则为true(返回a   非空值)并且没有干预电话关闭

答案 1 :(得分:0)

ofstream newFile(fileName);  

不仅仅是创建文件,它也会打开它。这意味着你无法再次打开它。

我没有看到删除文件的原因,重新创建它 - 截断它是否存在 - 并打开它,写一点,关闭文件,再次打开它但是但是附加,然后再写一些。

另外,如果运气不好,可以让其他流程在第一个close和第二个open之间修改(或删除)文件,这是一般来说不是一件好事。

此代码段应该有效:

bool rebuildFile()
{
   std::ofstream newFile(fileName);
   if (newFile)
   {
      newFile << fileHeader << endl;
      for (int i = 0; i < myVector.size(); i++) {
         newFile << myVector[i] << endl;
      }
   }
   return newFile;
}

(如果需要,ofstream的析构函数会自动关闭文件。)