Redirecting function output to /dev/null
Asked Answered
C

3

23

I am using a library that is printing a warning message to cout or cerr. I don't want this warning message to reach the output of my program. How can I catch this output and put it into /dev/null or similar?

MWE:

#include <iostream>

void foo()
{
    std::cout << "Boring message. " << std::endl;
};

int main()
{
    foo();
    std::cout << "Interesting message." << std::endl;
    return 0;
}

The output should be:

Interesting message.

How should I modify main to get the desired output? (foo must not be changed.)


I tried using freopen() and fclose(stdout) as suggested in this question How can I redirect stdout to some visible display in a Windows Application?. The result is that nothing is printed.

Chlodwig answered 23/11, 2011 at 17:13 Comment(1)
freopen is definitely the best-practice to be applied in this case.Devitalize
F
20

If you are sure that thing does not redirect output (e.g. to /dev/tty/, which would be standard-out again) (which I don't think), you could redirect before calling them.

#include <iostream>
#include <sstream>

void foobar() { std::cout << "foobar!\nfrob!!"; }

int main () {    
    using namespace std;

    streambuf *old = cout.rdbuf(); // <-- save        
    stringstream ss;

    cout.rdbuf (ss.rdbuf());       // <-- redirect
    foobar();                      // <-- call
    cout.rdbuf (old);              // <-- restore

    // test
    cout << "[[" << ss.str() << "]]" << endl;
}
Felting answered 23/11, 2011 at 17:30 Comment(1)
Or you can just install a null std::streambuf pointer, since it’s defined that output does nothing in that case.Mixon
R
25

May I suggest a hack? Set a bad/fail bit on the relevant stream before use of a library function.

#include <iostream>

void foo()
{
    std::cout << "Boring message. " << std::endl;
}

int main()
{
    std::cout.setstate(std::ios::failbit) ;
    foo();
    std::cout.clear() ;
    std::cout << "Interesting message." << std::endl;
    return 0;
}
Retinite answered 23/11, 2011 at 17:21 Comment(4)
Thank you this works, however, I've decided to mark the other answer as the accepted answer.Chlodwig
Thanks @Unapiedra. Manners always appreciated :)Retinite
Might I suggest saving the current state through rdstate and then resetting it to that afterwards? That's a little bit safer than clearing the stream's state.Mawson
@GuyGreer don't think that would be an issue for cout at least as if a fail or bad bit was set beforehand then it's not going to output anyway, and you'd probably want to clear that or find out why a bad bit was set. I wouldn't want to polish it up too much as it is a hack and there are other excellent answers to this question availableRetinite
F
20

If you are sure that thing does not redirect output (e.g. to /dev/tty/, which would be standard-out again) (which I don't think), you could redirect before calling them.

#include <iostream>
#include <sstream>

void foobar() { std::cout << "foobar!\nfrob!!"; }

int main () {    
    using namespace std;

    streambuf *old = cout.rdbuf(); // <-- save        
    stringstream ss;

    cout.rdbuf (ss.rdbuf());       // <-- redirect
    foobar();                      // <-- call
    cout.rdbuf (old);              // <-- restore

    // test
    cout << "[[" << ss.str() << "]]" << endl;
}
Felting answered 23/11, 2011 at 17:30 Comment(1)
Or you can just install a null std::streambuf pointer, since it’s defined that output does nothing in that case.Mixon
D
8

Use ios::rdbuf:

#include <iostream>

void foo()
{
    std::cout << "Boring message. " << std::endl;
}

int main()
{
    ofstream file("/dev/null");

    //save cout stream buffer
    streambuf* strm_buffer = cout.rdbuf();

    // redirect cout to /dev/null
    cout.rdbuf(file.rdbuf());

    foo();

    // restore cout stream buffer
    cout.rdbuf (strm_buffer);

    std::cout << "Interesting message." << std::endl;
    return 0;
}
Darken answered 23/11, 2011 at 17:26 Comment(1)
This doesn't work. You have to #include <fstream> and to prefix std:: where needed, e.g. std::ofstream and others.Webfooted

© 2022 - 2024 — McMap. All rights reserved.