提问人:JensB 提问时间:9/23/2023 更新时间:9/23/2023 访问量:64
为什么使用 freopen() 和 stderr 重定向 assert() 的输出可以工作,而在正常重定向 std::cerr 的缓冲区时却不能?
Why does redirecting the output of assert() work when done using freopen() and stderr but not when redirecting the buffer of std::cerr normally?
问:
我想重定向断言失败时创建的输出,以便将其写入日志文件而不是输出窗口。我假设用于输出,但是当重定向到我的日志文件时,仍然输出到输出窗口而不是我的文件: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 答案,但只需添加到 Visual Studio 项目属性中的命令行即可。这确实删除了错误,现在正确地输出到我的日志文件中。freopen
_CRT_SECURE_NO_WARNINGS
assert()
但这一切似乎不必要地复杂。感觉应该有一种平稳的方法来实现我想做的事情,而不会抑制 3 级编译器警告。为什么我不能简单地简单地重定向用于输出的任何内容的缓冲区?究竟用什么来输出,如果不是 ,或者?(我试过重定向所有三个)assert()
assert()
std::cout
std::cerr
std::clog
答:
您的进程有一个名为 的操作系统缓冲区,这是打印到的地方,因为它是一个 C 函数,另一方面是一个 C++ 对象,它将推送到 std::cerr 的文本打印到缓冲区。stderr
assert
std::cerr
stderr
修改对象将更改将打印到的缓冲区,但它不会修改直接打印的底层操作系统缓冲区,以便修改您需要特定于操作系统的功能,例如 or(其实现由操作系统定义,因为它们正在修改操作系统缓冲区)std::cerr
std:cerr
stderr
assert
freopen
dup2
评论
assert()
_CRT_SECURE_NO_WARNINGS
freopen_s
stderr
freopen
assert