将函数的std输出附加到文件中

Append std output of a function to a file

本文关键字:文件 输出 函数 std      更新时间:2023-10-16

假设我有一个函数。它将输出打印到std.out。有没有办法单独捕获函数的打印输出?然后将捕获的输出附加到文件中。

如果你不想像a.out >> output.txt那样重定向程序输出(这将重定向所有输出),你可以将std::cout重定向到一个文件(假设你也不想修改f()中的代码以使用fstream

简单示例:

#include <iostream>
#include <fstream>
#include <streambuf>
void f()
{
    std::cout << "Say somethingn";
}
int main()
{
    std::cout << "Writing to file..." << std::endl;
    std::ofstream ofile("output.txt", std::fstream::app); // output file
    std::streambuf *oldbuf = std::cout.rdbuf(); // save the buffer
    std::cout.rdbuf(ofile.rdbuf()); //redirect to output.txt
    f(); // call f
    // now redirect back
    std::cout.rdbuf(oldbuf);
    std::cout << "Done writing to file" << std::endl;
}

注意:如果您使用std::cout打印而不使用prinf,则以上操作有效。您甚至可以编写一个类似RAII的类,自动重定向cout,其析构函数重定向回,如下所示:

#include <iostream>
#include <fstream>
#include <streambuf>
class RAIIcout_redirect
{
    std::streambuf* _oldbuf;
public:
    RAIIcout_redirect(std::ofstream& os): _oldbuf(std::cout.rdbuf())
    {
        std::cout.rdbuf(os.rdbuf());
    }
    ~RAIIcout_redirect()
    {
        std::cout.rdbuf(_oldbuf);
    }
};
void f()
{
    std::cout << "Say somethingn";
}
int main()
{
    std::cout << "Writing to file..." << std::endl;
    std::ofstream ofile("output.txt", std::fstream::app); // output file
    // local scope, at exit cout is redirected back automatically
    {
        RAIIcout_redirect tmp(ofile);
        f(); // call f
    } // now redirect back because of ~RAIIcout_redirect()
    std::cout << "Done writing to file" << std::endl;
}

如果您有权访问函数src,您可以修改签名以传递给您希望该函数写入的ostream。添加一个默认值以最大限度地减少对其他调用的影响。

标题:

void foo(int x, int y, std::ostream& an_ostream = std::cout);

实现:

void foo(int x, int y, std::ostream& an_ostream)
{
    an_ostream << ...

用法out to std::out:

foo(1,2);

文件用法(使用字符串流模拟):

std::stringstream ss;
foo(3,4,ss);

输出到cerr:

foo(5,6,std::cerr);

抑制输出:

std::ofstream nullDev; // do not open
// set error, ignore errors
nullDev.setstate(std::ios_base::badbit); 
// do not close
foo(7,8,nullDev);

这里有一个疯狂的建议。

  1. 在函数的每一行输出前加上一个唯一的标记
  2. 然后,使用:
 a.out | grep <token> | sed -e '1,$s/<token>//' >> output.txt