Getting stdout contents without disabling cout/cin

眉间皱痕 提交于 2020-01-15 12:33:09

问题


Is it possible to save terminal (previously) written contents (stdout), to an array of strings:

vector<string> lines;

without disabling cin/cout normal functionality, in a linux console application.

In a terminal window in addition to characters there's coloring information for each character. Is there a way to save them in another array?


回答1:


If you mean you want to write inside a program to std::cout and have the data appear both on the terminal and in some program-internal data structure, you would use a custom stream buffer. Here us a simple example of how this would look:

#include <streambuf>
#include <iostream>

struct capturebuf
    : std::streambuf
{
    std::ostream&   d_out;
    std::streambuf* d_sbuf;
    std::string&       d_str;
public:
    capturebuf(std::ostream& out, std::string& str)
        : d_out(out)
        , d_sbuf(out.rdbuf())
        , d_str(str)
    {
        out.rdbuf(this);
    }
    ~capturebuf() {
        this->d_out.rdbuf(this->d_sbuf);
    }
    int overflow(int c) {
        if (c != std::char_traits<char>::eof()) {
            this->d_str.push_back(c);
        }
        return this->d_sbuf->sputc(c);
    }
    int sync() { return this->d_sbuf->pubsync(); }
};

The above stream buffer will just add each character written to the string referenced during construction. The characters are also forwarded to the passed stream buffer. The forwarding to pubsync() is needed to make sure the underlying stream is flushed at the appropriate times.

To actually use it, you need to install it into std::cout. Since the constructor and destructor of capturebuf already do the registration/deregistration, all it takes is to construct a corresponding object:

int main()
{
    std::string capture;
    {
        capturebuf buf(std::cout, capture);
        std::cout << "hello, world\n";
    }
    std::cout << "caught '" << capture << "'\n";
}

This code doesn't quite do what you asked but nearly: you'd just need to process newlines differently. What is entirely missing is buffering which isn't needed to get the functionality but to get the performance. The above was typed in on a mobile device and is provably riddled with typos but the approach should work as is.



来源:https://stackoverflow.com/questions/18631518/getting-stdout-contents-without-disabling-cout-cin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!