c++ - 如何在不重新创建现有文件的情况下写入 .txt 文件
问题描述
我有基本的日志记录过程。当程序中发生错误时,它必须记录到 .txt 文件中。我为此使用以下代码:
#include <fstream>
fileName = "logs/error_log.txt";
ofstream myfile;
myfile.open (fileName,fstream::app);
myfile << serialized_string << endl;
myfile.close();
发生错误时,它会成功转到 error_log.txt 文件。但是当程序崩溃并随后重新启动时,新日志不会记录为追加。正如预期的那样,我使用的方式创建了一个具有相同名称的新文件并在其上写入。有人可以解释一下我应该如何编写旧日志吗?
编辑:这些是我面临的步骤:我正在使用 raspbian,我编译如下:
g++ main.cpp -lwiringPi -lpthread -lcurl -o test
这就是整个功能。
int putLog(const char* process, int logType, string logData) {
isLoggerBusy = true;
string fileName;
std::string color;
switch (logType) {
case 0:
fileName = "logs/error_log.txt";
// color = "\033[0;31m";
break;
case 1:
fileName = "logs/info_log.txt";
// color = "\033[0;36m";
break;
case 2:
fileName = "logs/state_log.txt";
// color = "\033[1;33m";
break;
}
if (process == "WebSocket") {
color = "\033[1;32m";
}
json j = {
{"Process", process}, {"Time", currentDateTime()}, {"Log", logData}};
string serialized_string = j.dump();
fix_utf8_string(serialized_string);
ofstream myfile;
myfile.open(fileName, fstream::app);
cout << color << serialized_string << '\n';
myfile << serialized_string << endl;
myfile.close();
isLoggerBusy = false;
cout << "\033[0m" << endl;
return 0;
}
- 我启动了程序。它将这些行写到 state_logs.txt
{"Log":"传入消息{\"Action\":\"Heartbeat\",\"Data\":null}","Process":"WebSocket","Time":"2018-08-16.14: 53:52"}
{"Log":"GSM 设置完成","Process":"SMSService","Time":"2018-08-16.14:54:13"}
- 用 CTRL-C 停止程序并控制 state_logs.txt,我现在可以看到那里有两行。
- 重新启动程序并在 10 秒内再次使用 CTRC-C 中断(在新行记录之前)。
- 我再次检查了 state_logs.txt,现在我什么也看不到。重新执行此过程,但这次在中断程序之前等待多一点(只需要多一点才能获得一行日志。)。所以现在我只能看到一个并且时间戳已更改。
解决方案
我无法重现 OP 描述的内容。
我刚刚在cygwin /Windows 10 上进行了测试。(我不知道如何在在线编译器上进行此测试。)
testFStreamApp.cc
:
#include <iostream>
#include <fstream>
int main()
{
std::cout << "Log error...\n";
{ std::ofstream log("testFStream.log", std::ios::out | std::ios::app);
log << "Error happened!" << std::endl;
}
std::cout << "Going to die...\n";
abort();
return 0; // should never be reached
}
测试会话:
$ g++ -std=c++11 -o testFStreamApp testFStreamApp.cc
$ rm testFStream.log
$ for i in 1 2 3; do
> echo "$i. start:"
> ./testFStreamApp
> done
1. start:
Log error...
Going to die...
Aborted (core dumped)
2. start:
Log error...
Going to die...
Aborted (core dumped)
3. start:
Log error...
Going to die...
Aborted (core dumped)
$ cat <testFStream.log
Error happened!
Error happened!
Error happened!
$
YSC 指出我做了一些无声的改变。我假设没有相关性就这样做了。
但是,为了消除任何借口,我也尝试过:
#include <iostream>
#include <fstream>
int main()
{
std::cout << "Log error...\n";
std::ofstream log;
log.open("testFStream.log", std::fstream::app);
log << "Error happened!" << std::endl;
log.close();
std::cout << "Going to die...\n";
abort();
return 0; // should never be reached
}
输出与上面完全相同。
我不敢测试这个,但 Doctorlove 鼓励我:
#include <iostream>
#include <fstream>
int main()
{
std::cout << "Log error...\n";
std::ofstream log;
log.open("testFStream.log", std::fstream::app);
log << "Error happened!" << std::endl;
std::cout << "Going to die...\n";
abort();
log.close();
return 0; // should never be reached
}
即使在这种情况下,我也得到了相同的结果。
在这一点上,我必须承认 cygwin 只是 win32 API 的一个包装器。因此,在这种情况下,我不会怀疑这在其他操作系统上是否表现不同。
我知道这std::endl
确实有flush()
洞察力。问题是有效的(进入系统)多远flush()
。(在日常工作中,我尝试以一种不需要依赖这些细节的方式编写代码......);-)
推荐阅读
- c# - 自定义验证属性在客户端不起作用
- ruby-on-rails - 尝试创建新的 rails 5.1.4 项目时出现“找不到 gem”错误
- xcode-ui-testing - 两个模拟器上的单个 UITest 案例
- r - 使用 ggplot2 为并排图添加数据点
- c# - 通过 ClickOnce 部署 CefSharp Winform 并要求 Visual Studio 2019 中的 vc redist - 错误
- c - 程序以 3221225477 退出
- javascript - 如何在 JavaScript 中的同一行上绘制两个移动点
- c# - 传入的模型项是“LoginModel”类型,但此实例需要“HomeViewModel”类型的模型项
- sql - SQL Server:查找非重复项
- c# - 如何获得返回三元组并将其放入三个变量的方法的输出?