passingbyou
passingbyou

Reputation: 45

Append std output of a function to a file

Say I have a function. It has prints that output to std.out. Is there a way to capture the print outs of the function alone? Then append the captured output to a file.

Upvotes: 1

Views: 1064

Answers (3)

2785528
2785528

Reputation: 5566

If you have access to the function src, you can modify the signature to pass in the ostream to which you want that function to write. Add a default to minimize impact to the other invocations.

header:

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

implementation:

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

usage out to std::out:

foo(1,2);

usage to file (simulated with stringstream):

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

output to cerr:

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

suppress output:

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

foo(7,8,nullDev);

Upvotes: 1

vsoftco
vsoftco

Reputation: 56557

If you don't want to redirect the program output like a.out >> output.txt (this will redirect all output), you can redirect std::cout to a file (assuming also you don't want to modify the code in f() to use a fstream)

Simple example:

#include <iostream>
#include <fstream>
#include <streambuf>

void f()
{
    std::cout << "Say something\n";
}

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;
}

Note: the above works if you print with std::cout and not using prinf. You can even write a RAII-like class that automatically redirects cout and its destructor redirects back, like this:

#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 something\n";
}

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;
}

Upvotes: 2

R Sahu
R Sahu

Reputation: 206627

Here's a wild suggestion.

  1. Prepend every line of output from the function by a unique token.
  2. Then, use:
 a.out | grep <token> | sed -e '1,$s/<token>//' >> output.txt 

Upvotes: 0

Related Questions