redirect stdout/stderr to file under unix c++ - again

前端 未结 6 987
说谎
说谎 2021-02-15 15:51

What I want to do

redirect stdout and stderr to one or more files from inside c++

Why I need it

I am using an external, pr

相关标签:
6条回答
  • 2021-02-15 16:05

    For C++ iostreams, you can use the non-const overload of rdbuf to set std::cout to a std::filebuf. (This is best done by means of an RAII class, since you have to restore it before leaving main.) For C FILE*, you can use freopen, but I don't think you'll be able to restore it.

    FWIW: both of these solutions use only standard C++ or C, so should be portable.

    0 讨论(0)
  • 2021-02-15 16:06

    I was inspired by @POW and @James Kanze 's answers and put together a little RAII class for redirecting std::cout to a file. It is intended to demonstrate the principle.

    Code:

    #include <iostream>
    #include <fstream>
    #include <string>
    
    // RAII for redirection
    class Redirect {
        public:
        
        explicit Redirect(const std::string& filenm):
            _coutbuf{ std::cout.rdbuf() },   // save original rdbuf
            _outf{ filenm }
        {
            // replace cout's rdbuf with the file's rdbuf
            std::cout.rdbuf(_outf.rdbuf());
        }
        
        ~Redirect() {
            // restore cout's rdbuf to the original
            std::cout << std::flush;
            _outf.close();    ///< not really necessary
            std::cout.rdbuf(_coutbuf); 
        }
        
        private:
        
        std::streambuf* _coutbuf;
        std::ofstream _outf;
    };
    
    // == MAIN ==
    
    int main(int argc, char* argv[]) {
        std::cout << "This message is printed to the screen" << std::endl;
        {
            // scope for the redirection
            Redirect redirect{ "output.txt" };
            std::cout << "This message goes to the file" << std::endl;
        }
        std::cout << "Printing to the screen again" << std::endl;
    }
    

    Output:

    This message is printed to the screen

    Printing to the screen again

    Contents of the file "output.txt":

    This message goes to the file

    0 讨论(0)
  • 2021-02-15 16:07

    well i u'd better use freopen()

    Usage Syntax:

    freopen("RedToFile","r",stdout);
    or
    freopen("/dev/null","a",stdout);
    

    the same goes for "stderr"

    0 讨论(0)
  • 2021-02-15 16:09

    Are you looking for something like this :-

    int main()
    {
        // Save original std::cin, std::cout
        std::streambuf *coutbuf = std::cout.rdbuf();
        std::streambuf *cinbuf = std::cin.rdbuf(); 
    
        std::ofstream out("outfile.txt");
        std::ifstream in("infile.txt");
    
        //Read from infile.txt using std::cin
        std::cin.rdbuf(in.rdbuf());
    
        //Write to outfile.txt through std::cout 
        std::cout.rdbuf(out.rdbuf());   
    
        std::string test;
        std::cin >> test;           //from infile.txt
        std::cout << test << "  "; //to outfile.txt
    
        //Restore back.
        std::cin.rdbuf(cinbuf);   
        std::cout.rdbuf(coutbuf); 
    
    }
    

    From my earlier answer

    0 讨论(0)
  • 2021-02-15 16:13

    In addition to afr0ck answer of freopen() I want to say that while using freopen() we should be careful. Once a stream like stdout or stdin is reopened with assigning the new destination(here the 'output.txt' file) always it remains for a program unless it has been explicitly change.

    freopen("output.txt", "a", stdout);
    

    Here the standard output stream stdout is reopened and assigned with the 'output.txt' file. After that whenever we use printf() or any other stdout stream like - putchar() then every output will goes to the 'output.txt'. To get back the default behavior (that is printing the output in console/terminal) of printf() or putchar() we can use the following line of code -

    • for gcc, linux distribution like ubuntu - freopen("/dev/tty", "w", stdout);
    • for Mingw C/C++, windows - freopen("CON", "w", stdout);

    See the code example below -

    #include <stdio.h>
    
    int main() {
        
        printf("No#1. This line goes to terminal/console\n");
    
        freopen("output.txt", "a", stdout);
        printf("No#2. This line goes to the \"output.txt\" file\n");
        printf("No#3. This line aslo goes to the \"output.txt\" file\n");
    
        freopen("/dev/tty", "w", stdout); /*for gcc, diffrent linux distro eg. - ubuntu*/
        //freopen("CON", "w", stdout); /*Mingw C++; Windows*/
        printf("No#4. This line again goes to terminal/console\n");        
    
    }
    

    This code generate a 'output.txt' file in your current directory and the No#2 and No#3 will be printed in the 'output.txt' file.

    Thanks

    0 讨论(0)
  • 2021-02-15 16:17

    If you want to be able to reuse it, don't close stdoutfd in restore_stdout.

    0 讨论(0)
提交回复
热议问题