我想重定向
assert()
在断言失败时创建的输出,以便将其写入日志文件而不是输出窗口。我假设 assert()
使用 std::cerr
来输出,但是当将 std::cerr
重定向到我的日志文件时,assert()
仍然输出到输出窗口而不是我的文件:
std::ofstream ofs("log-file.txt");
std::cerr.rdbuf(ofs.rdbuf());
assert(false); // Still outputs "Assertion failed: false" to the output window and not to the log file
我发现了一个具有类似问题的SO问题,其答案建议使用
freopen
代替,如下所示:
freopen("log-file.txt", "w", stderr);
这给了我一个错误:
'freopen': This function or variable may be unsafe. Consider using freopen_s instead.
freopen_s
似乎采用与 freopen
不同的参数,我无法让它工作。
另一个SO答案建议使用
freopen
,但只需将_CRT_SECURE_NO_WARNINGS
添加到Visual Studio项目属性中的命令行即可。这确实消除了错误,并且 assert()
现在可以正确输出到我的日志文件。
但这一切似乎不必要地复杂。感觉应该有一种顺利的方法来实现我想做的事情,而不抑制 3 级编译器警告。为什么我不能简单地正常重定向
assert()
用于输出的缓冲区?如果不是 assert()
、std::cout
或 std::cerr
,那么 std::clog
到底用来输出什么? (我尝试过重定向所有三个)
你的进程有一个名为
stderr
的操作系统缓冲区,这是 assert
打印到的地方,另一方面 std::cerr
是一个 C++ 对象,它打印被推入 std::cerr 到 stderr
的文本缓冲液。修改
std::cerr
对象将更改
std:cerr
将打印到的缓冲区,但不会修改底层操作系统
stderr
缓冲区,其中
assert
直接打印,为了修改您需要特定于操作系统的功能,例如
freopen
或
dup2
(其实现由操作系统定义)