Вопрос по c++, stdout, unit-testing, legacy-code – Перенаправить cout и stdout в строку в C ++ для модульного тестирования

27

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

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

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

Edit

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

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

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

Ни один из ответов ниже не сработал для меня, у вас есть рабочий пример для этого? rraallvv

Ваш Ответ

4   ответа
-4

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

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

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

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

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

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

Посмотрите этот ответ, чтобы избежать "взлома NUL" в системах POSIX:stackoverflow.com/a/19499003/1557062
Вы приняли ваш ответ, так как stringstream был хорошим указателем, и ваш UPDATE примерно такой же, как мы, вероятно, доберемся без написания какого-то чрезвычайно большого запутанного беспорядка, сейчас я думаю, что я просто напишу в файл, и, надеюсь, мне не понадобится вывод printf для многих испытаний. thelsdj
Работает хорошо, но если я использую несколько модульных тестов, некоторые из них заканчиваются с исключением, потому что буфер уже освобожден и в него записан стандартный вывод. В случае только временного перенаправления в буфер используйтеsetbuf(stdout, NULL); в конце использования.
2

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

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

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

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

IOFBF из _IOFBF? Я должен был использовать последний, чтобы заставить это работать
Я хочу полностью отключить вывод на консоль, сохранив только захваченный буфер, возможно ли это?
2

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

В этот момент вы должны поразить операционную систему.
Я действительно хотел бы пропустить необходимость использования файловой системы. Что-то, что использует только оперативную память, будет лучше. thelsdj

Похожие вопросы