gpt4 book ai didi

C++ - 将 stdout/stderr 复制到文件,同时保留控制台输出

转载 作者:行者123 更新时间:2023-11-28 01:54:10 30 4
gpt4 key购买 nike

这里已经提出了非常相似的问题: Writing to both terminal and file c++

但没有一个好的答案。所有答案都建议使用自定义流或复制 std::cout。但是我需要 stdout/stderr 的行为。

想要的行为:对于每次写入 stdout/stderr,我都希望它出现在控制台上,并且也被重定向到一个文件。

我正在考虑将标准输出重定向到管道并从那里写入文件和控制台 - 扩展这个答案 https://stackoverflow.com/a/956269/2308106

有没有更好的方法来解决这个问题?

EDIT1: 为什么是 stdout/stderr 而不是自定义流?

我正在调用(第 3 方)我无法修改的代码,该代码托管在我的流程中。所以我不能使用自定义流(调用的代码已经写入 stderr/stdout)。

编辑 2:

根据 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 被重定向并且我写信给它;管道接收一遍又一遍地使用相同的非打印字符)

最佳答案

您可以通过替换指针来“劫持”stdout 和 stderr; stdout 和 stderr 只不过是 FILE *。我建议您先打开一个管道对,然后使用 fdopen() 创建一个新的 FILE * 与管道的发送端相关联,然后将 stdout 指向您的新 FILE。使用管道的接收端提取写入“旧”标准输出的内容。

伪代码:

int fd[2];
FILE *old_stdout, *new_stdout;

pipe(fd);
new_stdout = fdopen(fd[1], "w");
old_stdout = stdout;
stdout = new_stdout;

现在,您从 fd[0] 读取的所有内容都可以写入文件、old_stdout 等。

关于C++ - 将 stdout/stderr 复制到文件,同时保留控制台输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41832327/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com