Перенесите оба cout и stdout на строку в С++ для Unit Testing

Я работаю над получением некоторого устаревшего кода в модульных тестах, и иногда единственный способ распознать существующее поведение программы - это вывод консоли.

Я вижу много примеров в Интернете, чтобы перенаправить stdout на другой файл на С++, но есть ли способ перенаправить его на поток в памяти, поэтому мои тесты не должны полагаться на диск?

Я хотел бы получить что-то, что старый код отправляет в stdout в std::string, поэтому я могу легко .find на выходе.

Edit

Устаревший код настолько плохой, что он представляет собой смесь cout << .. и printf. Вот что я до сих пор:

void TestSuite::setUp(void)
{
    oldStdoutBuf = std::cout.rdbuf();
    std::cout.rdbuf(consoleOutput.rdbuf());
}
void TestSuite::tearDown(void)
{
    std::cout.rdbuf(oldStdoutBuf);
}

Проблема заключается в том, что это делает не вывод вывода с использованием printf. Я бы хотел, чтобы что-то получило и то, и другое. Любые идеи?

Ответ 1

std::stringstream может быть тем, что вы ищете.

UPDATE
Хорошо, это немного взломать, но, возможно, вы можете сделать это, чтобы захватить вывод printf:

char huge_string_buf[MASSIVE_SIZE];
freopen("NUL", "a", stdout);
setbuf(stdout, huge_string_buffer);

Обратите внимание, что вместо linux вместо "NUL" следует использовать "/dev/null". Это быстро начнет заполнять огромный_страничный_буфер. Если вы хотите продолжить перенаправление вывода после заполнения буфера, вам придется вызвать fflush(), иначе он выдает ошибку. Подробнее см. std::setbuf.

Ответ 2

Вы можете использовать freopen(..., stdout), а затем выгрузить файл в память или std::string.

Ответ 3

Это может быть альтернатива:

char bigOutBuf[8192];
char savBuf[8192];

fflush(stdout);
setvbuf(stdout,bigOutBuf,IOFBF,8192);//stdout uses your buffer

//after each operation
strncpy(savBuf,bigOutBuf,8192);//won't flush until full or fflush called

//...

//at long last finished
setbuf(stdout,NULL);//reset to unnamed buffer

Это просто перехватывает буферный вывод, поэтому он все равно идет на консоль или где угодно.

Надеюсь, что это поможет.

Ответ 4

Попробуйте sprintf, что более эффективно.

int i;
char str[] = "asdf";
char output[256];
sprintf(output, "asdfasdf %s %d\n", str, i);