可通过重定向std::cout的streambuf到文件流实现自动日志记录,无需手动逐条写入文件。

在C++程序中将控制台标准输出(std::cout)重定向到本地日志文件,可避免手动逐条调用file
使用freopen重定向stdout(C风格,简单直接)
第一步:在main函数开头立即调用freopen,将stdout绑定到指定日志文件。
freopen("app.log", "w", stdout);
第二步:后续所有printf、std::cout、std::cerr(注意:cerr默认不缓冲,但重定向后行为受文件流影响)输出都会写入app.log。
第三步:确保在程序退出前不调用fclose(stdout),否则std::cout后续操作会失败——C++流与FILE*底层共享同一文件描述符,fclose会关闭它并使std::cout处于失效状态。
注意:此方法会同时重定向C风格输出(printf)和C++风格输出(cout),但【无法单独控制cout的缓冲策略】,且重定向后无法轻易切回终端显示。
用std::streambuf自定义重定向(C++原生,可控性强)
创建一个文件流对象,并将其rdbuf()替换为std::cout的原始缓冲区,实现精细接管。
方法一:临时重定向单次输出块
std::ofstream file("app.log", std::ios::app);
std::streambuf* original = std::cout.rdbuf(file.rdbuf());
// 此后所有cout内容写入文件
std::cout // 恢复终端输出
std::cout.rdbuf(original);
方法二:全程接管并启用行缓冲(推荐)
std::ofstream log_file("app.log", std::ios::out | std::ios::app);
log_file.imbue(std::locale("")); // 支持中文等本地化字符
auto old_buf = std::cout.rdbuf(log_file.rdbuf());
std::cout
这一步必须在重定向后立即执行——【std::unitbuf是关键,否则程序异常终止时最后一行可能永远不落盘】。
绕过流缓冲,直接写入并强制刷新
当需要100%确保某条日志立刻落地(如错误现场快照),跳过cout缓冲链,直写文件描述符。
使用write系统调用(Linux/macOS)或WriteFile(Windows)虽高效,但失去格式化能力;更实用的做法是:
std::ofstream urgent("app.log", std::ios::app);
urgent urgent.flush();
这比依赖std::cout的全局重定向更可靠,适合关键路径日志。无需修改全局流状态,也无多线程竞争风险。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











