以下是我每次想要在日志文件中包含日期时必须编写的代码。我正在寻找一种方法,每次我想在我的文件中写一些东西时都不必写CurrentDateToString()
。
ofstream log;
log.open("test.log", ios_base::app);
log << CurrentDateToString() << " | " << "first line" << endl;
log << CurrentDateToString() << " | " << "second line" << endl;
log.close();
这是我的CurrentDateToString()
功能:
// convert date to formatted string
string CurrentDateToString()
{
time_t rawtime;
struct tm* timeInfo;
char buffer[80];
time(&rawtime);
timeInfo = localtime(&rawtime);
strftime(buffer, 80, "%Y-%m-%d %I:%M:%S", timeInfo);
string dateString(buffer);
return dateString;
}
这里的目标是能够编写这些行而不是我正在编写的当前行:
log << "first line" << endl;
log << "second line" << endl;
我是否必须编写日志类和重载运算符&lt;&lt;还是有其他办法吗?
答案 0 :(得分:1)
实现自动添加(或删除)字符的流(例如,添加日期)的方法是创建过滤流缓冲区。您从std::streambuf
派生了一个类,它将接收到的字符按摩到必要的形式,然后将它们转发到基础流缓冲区。
如果您在行的开头添加日期,则只需观察收到的换行符,如果有换行符,请设置标记need_date
。在设置need_date
时写入字符时,将写入日期并清除标记。
以下是查找日期的方法:
#include <streambuf>
class logbuf
: public std::streambuf {
std::streambuf* sbuf;
bool need_date{true};
using traits_type = std::char_traits<char>;
int overflow(int c) override {
if (c != traits_type::eof()) {
if (need_date) {
std::string date{CurrentDateToString()};
this->sbuf->sputn(date.c_str(), date.size());
need_date = false;
}
if (c == '\n') {
need_date = true;
}
return this->sbuf->sputc(c);
}
else {
return traits_type::not_eof(c);
}
}
int sync() override { return this->sbuf->pubsync(); }
public:
logbuf(std::streambuf* sbuf): sbuf(sbuf) {}
};
每次流缓冲区的缓冲区中没有空格时,都会调用virtual
函数overflow()
。由于没有为每个字符设置输出缓冲区(可以通过添加xsputn()
的覆盖和/或添加缓冲来提高性能。每次刷新流时都会调用函数sync()
。由于没有缓冲,因此只需将刷新请求转发到基础流缓冲区。
下面是一个使用此流缓冲区的简单演示。可以将创建合适的基础流缓冲区(例如std::filebuf
和std::ostream
)打包到派生自std::ostream
的类中。
#include <iostream>
int main()
{
logbuf sbuf(std::cout.rdbuf());
std::ostream logout(&sbuf);
logout << "hello\nwordl\n";
logout << "\n";
logout << "goodbye\n";
}