2009-07-21 4 views
27

Я работаю над получением некоторого устаревшего кода в модульных тестах, а иногда единственным способом распознавания существующего поведения программы является выход из консоли.Переадресовать как cout, так и stdout в строку на C++ для модульного тестирования

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

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

Редактировать

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

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

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

+0

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

ответ

14

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

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

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

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

+0

Принял ваш ответ, поскольку stringstream был хорошим указателем, и ваш UPDATE примерно такой, насколько мы, вероятно, получим, не нажимая какой-то чрезвычайно массивный запутанный беспорядок, на данный момент я думаю, что просто напишу в файл и надеюсь, что мне не понадобится printf вывода для многих тестов. – thelsdj

+3

Хорошо работает, но если я использую несколько модульных тестов, некоторые сбой исключаются из-за того, что буфер уже освобожден, и в него записывается stdout. В случае только временного перенаправления в буфер используйте 'setbuf (stdout, NULL);' в конце использования. – Martze

+0

См. Этот ответ, чтобы избежать «NUL» -Hack в системах POSIX: http://stackoverflow.com/a/19499003/1557062 – sigy

2

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

+0

Мне бы очень хотелось пропустить использование файловой системы. То, что использует только баран, было бы лучше. – thelsdj

+0

В этот момент вам нужно нажать на операционную систему. – MSN

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 

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

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

+1

IOFBF от _IOFBF?Я должен был использовать последний, чтобы получить эту работу. – Gayan

+0

Я хочу полностью отключить вывод консоли, сохраняя только захваченный буфер. – rraallvv

-4

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

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