我有一个库,可以将内容输出到控制台。
如何更改stdout以使其写入文件而不是控制台?
答案 0 :(得分:4)
答案 1 :(得分:1)
你可以只在close(1)
然后dup2
stdout(1)上的任何文件描述符。
答案 2 :(得分:0)
退一步,看起来你可能遇到了图书馆设计问题。
在许多图书馆中,您应该谨慎地编写用户未告诉您编写的任何地方。这意味着您根本不应该写入标准输出,当然也不会重定向它。不要忘记,程序的其他部分可能依赖于仍然作为标准输出的标准输出,而不是写入您的库想要给我们的文件。如果有必要在某处写入,则用户应该告诉您写入的位置,或者只需打开文件并让库写入该文件,而不是标准输出。如果出现错误,库可能可以写入标准错误,但即使这样你也应该谨慎。
显然,这里的冗余语句有例外(只需指向标准I / O库)。但是,为了方便库,您正在讨论从库中重定向标准输出的事实意味着设计是可疑的。
答案 3 :(得分:0)
您可以使用此课程:
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string>
class StdCapture
{
public:
StdCapture(): m_capturing(false), m_init(false), m_oldStdOut(0), m_oldStdErr(0)
{
m_pipe[READ] = 0;
m_pipe[WRITE] = 0;
if (_pipe(m_pipe, 65536, O_BINARY) == -1)
return;
m_oldStdOut = dup(fileno(stdout));
m_oldStdErr = dup(fileno(stderr));
if (m_oldStdOut == -1 || m_oldStdErr == -1)
return;
m_init = true;
}
~StdCapture()
{
if (m_capturing)
{
EndCapture();
}
if (m_oldStdOut > 0)
close(m_oldStdOut);
if (m_oldStdErr > 0)
close(m_oldStdErr);
if (m_pipe[READ] > 0)
close(m_pipe[READ]);
if (m_pipe[WRITE] > 0)
close(m_pipe[WRITE]);
}
void BeginCapture()
{
if (!m_init)
return;
if (m_capturing)
EndCapture();
fflush(stdout);
fflush(stderr);
dup2(m_pipe[WRITE], fileno(stdout));
dup2(m_pipe[WRITE], fileno(stderr));
m_capturing = true;
}
bool EndCapture()
{
if (!m_init)
return false;
if (!m_capturing)
return false;
fflush(stdout);
fflush(stderr);
dup2(m_oldStdOut, fileno(stdout));
dup2(m_oldStdErr, fileno(stderr));
m_captured.clear();
std::string buf;
const int bufSize = 1024;
buf.resize(bufSize);
int bytesRead = 0;
if (!eof(m_pipe[READ]))
{
bytesRead = read(m_pipe[READ], &(*buf.begin()), bufSize);
}
while(bytesRead == bufSize)
{
m_captured += buf;
bytesRead = 0;
if (!eof(m_pipe[READ]))
{
bytesRead = read(m_pipe[READ], &(*buf.begin()), bufSize);
}
}
if (bytesRead > 0)
{
buf.resize(bytesRead);
m_captured += buf;
}
return true;
}
std::string GetCapture() const
{
std::string::size_type idx = m_captured.find_last_not_of("\r\n");
if (idx == std::string::npos)
{
return m_captured;
}
else
{
return m_captured.substr(0, idx+1);
}
}
private:
enum PIPES { READ, WRITE };
int m_pipe[2];
int m_oldStdOut;
int m_oldStdErr;
bool m_capturing;
bool m_init;
std::string m_captured;
};
当您需要开始捕获时请致电BeginCapture()
当您需要停止捕获时请致电EndCapture()
调用GetCapture()
来检索捕获的输出