C++中ofstream创建文件但未写入内容的问题

4
我正在编写一个MFC程序,其中包含一个对话框和一个“导出”按钮,该按钮将把所有输入的数据导出到一个.txt文件(在某个时候我想将其更改为.msg文件...但这是另一天的问题)。
然而,当我点击按钮时,它会创建文件,但不会在文件中写入任何内容。为了测试,我删掉了除了一个简单的字面字符串以外的所有内容,甚至那个也没有打印出来。这是事件的当前代码:myfile.flush()语句是我尝试向文件打印循环时留下的。
void CEHDAHTTimerDlg::OnBnClickedExport()
{
    // in this function, we want to export the items to a text file
    std::ofstream myfile("TodayTime.txt");
    myfile.open("TodayTime.txt");
    if (myfile.is_open())
    {
        myfile << "The average call time is ";
        myfile.flush();
        myfile.close();
    }
    else
    {
        SetDlgItemText(IDC_EXPORT, L"Export Unsuccessful! --     No File");
    }
}

有什么可能导致这种情况的吗?我已经试了几个小时了,尝试使用 myfile.write() 函数等不同的方法。我在这里、Reddit和Google上搜索了很多,想知道为什么它没有写入。
感谢您的帮助。
编辑:
好的,按照我所做的方式调用 myfile 构造函数,包括文件名,就已经完成了打开文件的操作。
谢谢您的帮助!

myfile.open() 会为您创建文件(或者在您创建 ofstream 对象时)。我认为 myfile.is_open() 不是正确的条件函数。请研究如何检查文件是否打开并尝试其他函数。也许 !myfile.fail() 可以起作用。 - Khalil Khalaf
然而,当我点击按钮时,它会创建文件但不会在文件内写入任何内容。你调试过程序吗?你怎么知道它进入了 if 块? - PaulMcKenzie
为什么你既称之为打开文件的构造函数又称之为“open”?此外,你知道如何检查应用程序的工作目录吗? - SergeyA
需要阅读有关 std::ofstream 的工作方式。Sergey 已经注意到文件被打开了两次。在关闭之前立即刷新也是不必要的,因为关闭会自动刷新。同时,关闭也是不必要的,因为 ofstream 的销毁将在函数退出时发生并关闭文件。此外,还没有测试来确保写入成功。 - user4581301
3个回答

5

注释掉多余的"open"即可解决问题。

#include <iostream>
#include <fstream>

int main()
{
    // in this function, we want to export the items to a text file
    std::ofstream myfile("TodayTime.txt");
//    myfile.open("TodayTime.txt");
    if (myfile.is_open())
    {
        myfile << "The average call time is ";
        myfile.flush();
        myfile.close();
    }
    else
    {
        std::cerr << "didn't write" << std::endl;
    }
}

我强烈怀疑您正在调用未定义行为,因为您正在打开已经打开的流。

1
@SamuelOhrenberg :) 通常情况下,如果你知道要查找什么,那就没问题了。标准库非常简约,期望我们满足所有先决条件。通常情况下不会执行冗余检查。你会逐渐习惯它,并学会欣赏其所实现的性能和优雅。 - Richard Hodges
关于你的编辑,@SamuelOhrenberg。并不是说你不需要打开文件,而是在使用带有文件名的构造函数时已经打开了该文件。如果你使用默认构造函数,那么你随后就必须打开该文件。 - Richard Hodges
哦,我明白了。所以默认构造函数只是创建了一个“myfile”的实例,但它有一个选项可以包括文件的位置并自动打开它。 - Samuel Ohrenberg
@SamuelOhrenberg,ofstream(正如它的名称所示)是一个流。它在实际的文件处理之上添加了一层。构造函数使用文件名隐式调用open()作为构造函数的一部分。如果它处于打开状态,析构函数将自动刷新流并关闭底层文件。cppreference.com是阅读这些内容的好地方。http://en.cppreference.com/w/cpp/io/basic_ofstream - Richard Hodges
1
这里没有未定义行为: 调用open()将会失败,因为流已经与文件相关联,设置了failbit。调用is_open()将会成功,因为文件是打开的。然后对流操作符<<的调用将会失败(因为failbit) - 但是谁在检查呢? :) - Vlad Feinstein
@VladFeinstein 如果你把这个变成答案,我会点赞的。 - Richard Hodges

4

以下是解释:

  1. 调用 myfile.open("TodayTime.txt"); 会失败,因为流已经关联到该文件,设置了 failbit。
  2. 调用 is_open() 会成功,因为文件已经打开。
  3. 然后对流操作符 << 的调用将失败(因为 failbit)。

谢谢。那么,解决方案是什么? - quanta
@quanta 不要打开文件两次 :) - Vlad Feinstein

0

这是因为 myfile << "The average call time is "; 不起作用,要修复它

std::ofstream myfile;
myfile.open("TodayTime.txt",std::ios:app) //app for appending you can use trunc for
  //truncating file 
  //for flushing content's of existing file use myfile.flush();
if (!data_pack.is_open())
{
    std::cerr << "unable to open the file for writing";
}

 myfile << "some stuff tho write you can replace the string with variable"
  <<std::endl; //for next line
  //at last close file
   myfile.close();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接