【发布时间】:2017-06-09 11:54:36
【问题描述】:
这里已经提出了非常相似的问题: Writing to both terminal and file c++
但没有一个好的答案。所有答案都建议使用自定义流或复制 std::cout。但是我需要标准输出/标准错误的行为。
想要的行为:对于每次对 stdout/stderr 的写入,我希望它出现在控制台上并被重定向到一个文件。
我正在考虑将标准输出重定向到管道并从那里写入文件和控制台 - 扩展这个答案https://stackoverflow.com/a/956269/2308106
有没有更好的方法来解决这个问题?
EDIT1: 为什么是 stdout/stderr 而不是自定义流?
我正在调用我无法修改且托管在我的进程中的(第 3 方)代码。所以我不能使用自定义流(被调用的代码已经写入标准错误/标准输出)。
EDIT2:
根据 JvO 的建议,我尝试了我的实现(Windows):
HANDLE hPipe = ::CreateNamedPipe(TEXT("\\\\.\\pipe\\StdErrPipe"),
PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE,
//single instance
1,
//default buffer sizes
0,
0,
0,
NULL);
if (hPipe == INVALID_HANDLE_VALUE)
{
//Error out
}
bool fConnected = ConnectNamedPipe(hPipe, NULL) ?
TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);
if (!fConnected)
{
//Error out
}
int fd = _open_osfhandle(reinterpret_cast<intptr_t>(hPipe), _O_APPEND | /*_O_WTEXT*/_O_TEXT);
if (dup2(fd, 2) == -1)
{
//Error out
}
但仍然存在一些问题 - 因为从管道的另一端我只收到一个 rubish(我首先尝试直接发送一些东西 - 这很好用;但是一旦 stderr 被重定向并写入它;管道接收一遍又一遍地使用相同的不可打印字符)
【问题讨论】:
-
在您链接到的第一个问题中,请注意最佳答案只是一个执行两个输出的简单函数?一个到文件,一个到
std::cout?不能用类似的方法解决吗?通过创建一个您调用的函数,然后写入文件和stdout? -
为什么自定义流如此糟糕?现有的解决方案有什么问题?你只是不喜欢它们,因为它还不是
ostream的一部分? -
另外,您能否详细说明您需要写信给
stdout或stderr吗?您是否正在调用一些您无法修改的 C 函数?您试图解决的实际和原始问题是什么?请read about the XY problem 思考它与您的问题有何关系。 -
不,没有标准的类可以做你想做的事。