Get previous cout text to string

Dec 19, 2022 at 6:06pm
Need to get previous cout text to string.
Need to keep cout for debug
Tried sstring buffer, but it can replace cout
Dec 19, 2022 at 6:55pm
Use a program like tee from the shell
https://man7.org/linux/man-pages/man1/tee.1.html
Example:
./program | tee stdout.txt

Alternatively, write debug output to standard error (with std::cerr or std::clog) and redirect it to a file.
https://linux.die.net/man/1/bash (See section REDIRECTION)
Example:
./program 2> stderr.txt

To solve the problem using C++ code, the behavior of std::cout can be changed by replacing its underlying stream buffer. For example see this thread:
https://cplusplus.com/forum/general/97966/
Last edited on Dec 19, 2022 at 6:56pm
Dec 19, 2022 at 7:11pm
Is there alternative for tee on Windows?
Dec 19, 2022 at 7:33pm
Dec 19, 2022 at 7:49pm
There should be a direct Windows-equivalent, tee.exe, available somewhere on the web, but the one website I found that might have a link to it seems to be down. I have it locally on my machine. Try searching for something like "unix tools tee windows".
Last edited on Dec 19, 2022 at 7:49pm
Dec 19, 2022 at 9:17pm
I found analog for Windows for tee, but how to get terminal (output text) contains?
Dec 20, 2022 at 2:32am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <sstream>

namespace utility
{
    template < typename C, typename T = std::char_traits<C> >
    struct basic_teebuf : public std::basic_streambuf<C,T>
    {
        using streambuf_type = std::basic_streambuf<C,T> ;
        using int_type = typename T::int_type ;

        basic_teebuf( streambuf_type* buff_a, streambuf_type* buff_b )
            : first(buff_a), second(buff_b) {}

        protected:
            virtual int_type overflow( int_type c ) override
            {
                const int_type eof = T::eof() ;
                if( T::eq_int_type( c, eof ) ) return T::not_eof(c) ;
                else
                {
                    const auto ch = T::to_char_type(c) ;
                    return T::eq_int_type( first->sputc(ch), eof ) ||
                           T::eq_int_type( second->sputc(ch), eof ) ? eof : c ;
                }
            }

            virtual int sync() override { return !first->pubsync() && !second->pubsync() ? 0 : -1 ; }

        private:
            streambuf_type* first ;
            streambuf_type* second ;
    };

    using teebuf = basic_teebuf<char> ;
}

int main()
{
    // set up a tee to also send output of stdout to a string buffer
    std::stringbuf sbuf( std::ios_base::out ) ;
    const auto oldbuf = std::cout.rdbuf() ;
    utility::teebuf tbuf( oldbuf, std::addressof(sbuf) ) ;
    std::cout.rdbuf( std::addressof(tbuf) ) ;
    
    std::cout << "line #1: " << 1234 << '\n'
              << "line #2: " << 56.78 << '\n'
              << "line #3: " << 999 << ' ' << 999.999 << '\n' << std::flush ;

    std::cout.rdbuf(oldbuf) ; // restore old behaviour of cout

    const std::string str = sbuf.str() ; // retrieve the string from the string buffer
    
    std::cout << "\ntext in string str\n------------------\n" << str ;
}

http://coliru.stacked-crooked.com/a/a153648df1b8403b
Dec 20, 2022 at 2:50pm
for windows:

https://learn.microsoft.com/en-us/windows/console/readconsoleoutput?redirectedfrom=MSDN

I have not used it, but it sounds like it could do what you want.

you can also just make your own stuff, keeping the last output string every time you write out.
Dec 20, 2022 at 10:02pm
I 've tried win API variant but it's not clear for me
How to get data to string?
If print unichar set it just prints its standard and array members

Can you give me a clue how to get data from terminal and put it to string using link https://learn.microsoft.com/en-us/windows/console/reading-and-writing-blocks-of-characters-and-attributes?redirectedfrom=MSDN
Last edited on Dec 20, 2022 at 10:12pm
Dec 20, 2022 at 10:14pm
I found the way how to output data with tee to text, but there is no terminal output string yet
Please advise
Added
I have gcc version 4.9.1, can not use streambuf_type
Last edited on Dec 20, 2022 at 10:28pm
Dec 20, 2022 at 11:13pm
C++98, credits to JLBorges
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <iostream>
#include <sstream>

namespace utility
{
    template < typename C, typename T = std::char_traits<C> >
    struct basic_teebuf : public std::basic_streambuf<C,T>
    {
        typedef std::basic_streambuf<C,T> streambuf_type;
        typedef typename T::int_type int_type;

        basic_teebuf( streambuf_type* buff_a, streambuf_type* buff_b )
            : first(buff_a), second(buff_b) {}

        protected:
            virtual int_type overflow( int_type c )
            {
                const int_type eof = T::eof() ;
                if( T::eq_int_type( c, eof ) ) return T::not_eof(c) ;
                else
                {
                    const typename T::char_type ch = T::to_char_type(c) ;
                    return T::eq_int_type( first->sputc(ch), eof ) ||
                           T::eq_int_type( second->sputc(ch), eof ) ? eof : c ;
                }
            }

            virtual int sync() { return !first->pubsync() && !second->pubsync() ? 0 : -1 ; }

        private:
            streambuf_type* first ;
            streambuf_type* second ;
    };

    typedef basic_teebuf<char> teebuf;
}

int main()
{
    // set up a tee to also send output of stdout to a string buffer
    std::stringbuf sbuf( std::ios_base::out ) ;
    std::streambuf* const oldbuf = std::cout.rdbuf() ;
    utility::teebuf tbuf( oldbuf, &sbuf ) ;
    std::cout.rdbuf( &tbuf ) ;
    
    std::cout << "line #1: " << 1234 << '\n'
              << "line #2: " << 56.78 << '\n'
              << "line #3: " << 999 << ' ' << 999.999 << '\n' << std::flush ;

    std::cout.rdbuf(oldbuf) ; // restore old behaviour of cout

    const std::string str = sbuf.str() ; // retrieve the string from the string buffer
    
    std::cout << "\ntext in string str\n------------------\n" << str ;
}
Last edited on Dec 20, 2022 at 11:13pm
Topic archived. No new replies allowed.