Перенаправить как cout, так и stdout на строку в C++ для модульного тестирования

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

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

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

Изменить

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

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

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


person thelsdj    schedule 21.07.2009    source источник
comment
Ни один из приведенных ниже ответов не сработал для меня, у вас есть рабочий пример для этого?   -  person rraallvv    schedule 11.03.2016


Ответы (4)


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

ОБНОВЛЕНИЕ
Хорошо, это небольшая хитрость, но, возможно, вы могли бы сделать это, чтобы получить вывод printf:

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

Обратите внимание, что вы должны использовать «/dev/null» для Linux вместо «NUL». Это быстро начнет заполнять huge_string_buffer. Если вы хотите иметь возможность продолжить перенаправление вывода после заполнения буфера, вам придется вызвать fflush(), иначе он выдаст ошибку. См. std::setbuf для получения дополнительной информации.

person Gabe    schedule 21.07.2009
comment
Принял ваш ответ, поскольку stringstream был хорошим указателем, и ваше ОБНОВЛЕНИЕ примерно так далеко, как мы, вероятно, получим, не написав какой-то чрезвычайно массивный запутанный беспорядок, на данный момент я думаю, что просто напишу в файл и, надеюсь, мне не понадобится вывод printf для многих испытаний. - person thelsdj; 22.07.2009
comment
Работает хорошо, но если я использую несколько модульных тестов, некоторые из них терпят неудачу с исключением, потому что буфер уже освобожден, и в него записывается стандартный вывод. В случае только временного перенаправления в буфер используйте setbuf(stdout, NULL); в конце использования. - person Martze; 14.11.2014
comment
См. этот ответ, чтобы избежать взлома NUL в системах POSIX: stackoverflow.com/a/19499003/1557062 - person sigy; 16.11.2016

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

person MSN    schedule 21.07.2009
comment
Я действительно хотел бы пропустить необходимость использования файловой системы. Что-то, что использует только оперативную память, было бы лучше. - person thelsdj; 22.07.2009

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

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

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

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

person cvsdave    schedule 18.09.2009
comment
Я хочу полностью подавить вывод консоли, оставив только захваченный буфер. Возможно ли это? - person rraallvv; 12.03.2016

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

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