Перенаправить вывод функции печати на консоль в строку
позволяет сказать, что у нас есть функция, которая печатает текст на консоли и в котором мы не имеем контроля над исходным кодом, но мы можем его назвать. Например
void foo() {
std::cout<<"hello world"<<std::endl;
print_to_console(); // this could be printed from anything
}
Можно ли перенаправить вывод указанной выше функции в строку без изменения самой функции?
Я не ищу способ сделать это через терминал
Ответы
Ответ 1
Да. Это можно сделать. Вот небольшая демонстрация:
#include <sstream>
#include <iostream>
void print_to_console() {
std::cout << "Hello from print_to_console()" << std::endl;
}
void foo(){
std::cout<<"hello world"<<std::endl;
print_to_console(); // this could be printed from anything
}
int main()
{
std::stringstream ss;
//change the underlying buffer and save the old buffer
auto old_buf = std::cout.rdbuf(ss.rdbuf());
foo(); //all the std::cout goes to ss
std::cout.rdbuf(old_buf); //reset
std::cout << "<redirected-output>\n"
<< ss.str()
<< "</redirected-output>" << std::endl;
}
Вывод:
<redirected-output>
hello world
Hello from print_to_console()
</redirected-output>
Смотрите онлайн-демонстрацию.
Ответ 2
@Андр спросил в комментарии моего первого ответа:
Что произойдет, если они используют printf, puts, write и т.д.? - Андре Костур
Для printf
я придумал следующее решение. Он будет работать только на POSIX, поскольку fmemopen доступен только на POSIX, но вместо этого вы можете использовать временный файл, если хотите — это будет лучше, если вы хотите портативное решение. Основная идея будет такой же.
#include <cstdio>
void print_to_console() {
std::printf( "Hello from print_to_console()\n" );
}
void foo(){
std::printf("hello world\n");
print_to_console(); // this could be printed from anything
}
int main()
{
char buffer[1024];
auto fp = fmemopen(buffer, 1024, "w");
if ( !fp ) { std::printf("error"); return 0; }
auto old = stdout;
stdout = fp;
foo(); //all the std::printf goes to buffer (using fp);
std::fclose(fp);
stdout = old; //reset
std::printf("<redirected-output>\n%s</redirected-output>", buffer);
}
Вывод:
<redirected-output>
hello world
Hello from print_to_console()
</redirected-output>
Онлайн-демонстрация.
Ответ 3
class buffer
: public std::streambuf
{
public:
buffer(std::ostream& os)
: stream(os), buf(os.rdbuf())
{ }
~buffer()
{
stream.rdbuf(buf);
}
private:
std::ostream& stream;
std::streambuf* buf;
};
int main()
{
buffer buf(std::cout);
std::stringbuf sbuf;
std::cout.rdbuf(sbuf);
std::cout << "Hello, World\n";
}