2009-07-21 9 views
27

Sto lavorando per ottenere un codice legacy sotto test unitari e talvolta l'unico modo per rilevare un comportamento del programma esistente è l'output della console.Reindirizzare sia cout che stdout su una stringa in C++ per il test dell'unità

Vedo un sacco di esempi online su come reindirizzare lo stdout in un altro file in C++, ma c'è un modo per reindirarlo a un flusso in memoria, quindi i miei test non devono fare affidamento sul disco?

Mi piacerebbe ottenere tutto ciò che il codice legacy invia allo stdout in una stringa std :: :: così posso facilmente trovare l'output.

Modifica

Il codice legacy è così male che gli utenti una miscela di cout << .. e printf. Ecco quello che ho finora:

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

Il problema è che questo non uscita di cattura utilizzando printf. Mi piacerebbe qualcosa che ottenga entrambi. Qualche idea?

+0

Nessuna delle risposte di seguito ha funzionato per me, ne hai un esempio funzionante? – rraallvv

risposta

14

std::stringstream potrebbe essere quello che stai cercando.

UPDATE
Va bene, questo è un po 'di hack, ma forse si potrebbe fare questo per afferrare l'output printf:

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

Nota si dovrebbe usare "/ dev/null" per linux invece di "NUL". Questo inizierà rapidamente a riempire huge_string_buffer. Se vuoi essere in grado di continuare a reindirizzare l'output dopo che il buffer è pieno dovrai chiamare fflush(), altrimenti genererà un errore. Vedi std::setbuf per maggiori informazioni.

+0

Ho accettato la tua risposta come stringstream era un buon puntatore e il tuo UPDATE è circa quanto potremmo probabilmente ottenere senza scrivere un pasticcio enormemente complicato, per ora penso che scriverò su un file e spero di non aver bisogno della stampa uscita per molti test. – thelsdj

+3

Funziona bene, ma se uso test di unità multiple, alcuni falliscono con un'eccezione perché il buffer è già liberato e lo stdout è scritto in esso. In caso di solo un reindirizzamento temporaneo nel buffer usa un 'setbuf (stdout, NULL);' alla fine dell'uso. – Martze

+0

Vedere questa risposta per evitare il "NUL" -Hack sui sistemi POSIX: http://stackoverflow.com/a/19499003/1557062 – sigy

2

È possibile utilizzare freopen(..., stdout) e quindi scaricare il file in memoria o std::string.

+0

Mi piacerebbe davvero saltare dover usare il filesystem. Qualcosa che usa solo ram sarebbe la cosa migliore. – thelsdj

+0

A quel punto devi colpire il sistema operativo. – MSN

2

puo essere un'alternativa:

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 

Questa intercetta solo l'uscita tamponata, così va ancora console o ovunque.

Spero che questo aiuti.

+1

IOFBF di _IOFBF?Ho dovuto usare quest'ultimo per farlo funzionare – Gayan

+0

Voglio sopprimere l'output della console interamente, mantenendo solo il buffer catturato è possibile? – rraallvv

-4

Prova sprintf, è più efficiente.

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