亲爱的所有人:我有一个C ++项目(在Visual Studio 2008中),包含header.h,source_1.cpp文件,其中包含main()和source_2.cpp文件。
在程序的某些点,我需要将一些中间结果输出到文本文件中,比如“output.txt”。问题是,我无法做到这一点。也就是说,我无法将结果输出到source_1.cpp和source_2.cpp的相同“output.txt”文件中。我一直在使用ofstream进行写入文件操作。
例如,在source_1.cpp中,我说过
ofstream ofile("output.txt");
以后在代码中我会说,
ofile<<"Result of intermediate calculation are "<<intermediate_result<<endl;
将结果存储到output.txt。
在source_2.cpp中,事实证明我无法定义
extern ofstream ofile("output.txt");
(在多个地方定义了相同对象的错误。)
然后我尝试在source_2.cpp
中说ofstream ofile_2("output.txt");//Note ofile_2 which is different from ofstream ofile in source_1.cpp
但是,在source_2.cpp中使用ofile_2最终会将以前的输出删除到source_1.cpp中由ofile写入的文件中。
我是否应该使用ofstream以外的东西才能从两个不同的.cpp文件写入同一个文件?
感谢。
答案 0 :(得分:3)
最佳方法:将类型ostream&
的实例传递给需要输出结果的所有客户端。我建议抵制定义任何人可见的全局静态ostream
对象的诱惑......
答案 1 :(得分:2)
问题的核心是您使用两个不同的文件句柄来写入同一个文件。如果按顺序执行此操作,则没有问题。如果要附加到文件,则必须按如下方式打开它:
std::ofstream file("output.txt", std::ios_base::out | std::ios_base::app)
这将告诉ofstream
附加到文件。
为了避免编译单元之间的命名冲突,您可以使用namespaces。
答案 2 :(得分:1)
每次使用相同的文件名字符串构造ofstream
时,它都会覆盖已存在的字符串。
将ofstream
封装在构造它一次的类中,然后使用此包装类的全局可访问实例上的成员从其他类写入它。如果你不总是想写这个文件,这个类可以在第一次请求的写入时调用open()
。
或者(更快但是凌乱)只需在全球范围内声明ofstream
即可供所有人使用。
我通常不会鼓励任何形式的全局可见数据,但是日志文件是一个有意义的案例。
您可能需要实现互斥锁来调解并发写入。将ofstream
封装在FileWriter
类或类似内容中的另一个论点。如果不这样做,你可能会发现一个线程中的数据与另一个线程中的数据混淆地交错。
如果您希望日志记录需要变得更加复杂,您可以考虑log4cpp,而不是在逻辑的外围区域投入越来越多的时间。