2015-04-15 12 views
12

Ho il seguente codice:Perché questo codice che utilizza printf e cout non ha l'output previsto?

int main() 
{ 
    ios_base::sync_with_stdio(false); 
    cin.tie(NULL);  

    for (int i = 0; i < 3; i++) { 
     cout << i << " "; 
     printf("%d ", i); 
    } 

    cout << endl; 
    return 0; 
} 

i risultati attesi di questo codice è:

0 0 1 1 2 2

ma, invece, esso stampa:

0 1 2 
0 1 2 

Questo problema si verifica in Compilatore GNU G ++ 4.9.2

+1

Buffer separati? –

+2

@KerrekSB è esattamente questo e non voglio rubare la risposta da te. printf e cout utilizzano buffer separati che vengono svuotati in momenti diversi. Nel caso del codice di cui sopra, il cout è stato probabilmente scaricato in linea e printf è stato svuotato alla fine della chiamata. Sostituisci lo spazio nel printf con qualcos'altro (_) e lo vedrai. – IdeaHat

+0

Aggiungi 'fflush (stdout)'? – Columbo

risposta

10

Una possibile spiegazione di ciò è che cout e printf utilizzano buffer separati. cout uscite sullo schermo del terminale quando viene scaricata utilizzando il comando endl o se il buffer è pieno (generalmente 512 byte).

Non sono sicuro di printf (quindi sentitevi liberi di correggermi se ho torto), ma segue anche un comportamento simile. Quindi, quello che succede è che alla fine del programma, entrambi i buffer sono scaricati, e quindi l'output che si vede è raggiunto.

Ho eseguito il codice sulla mia macchina (GCC 4.8.1) insieme con la modifica come sotto

cout << i << " . "; 
printf("%d ", i); 

L'uscita ho osservato era 0 1 2 0 . 1 . 2 . che sembra indicare che le vampate printf primo nel mio caso. Non ho idea se è di progettazione (menzionato da qualche parte nello standard), o se dipende dal contesto.

+0

Piuttosto sicuro che 'cout' si svuota anche per i newline, sebbene la maggior parte degli istanti non lo faccia. –

+1

@MooingDuck: Da quello che ho letto, 'cout' si svuota per newline quando si esegue l'output su un dispositivo interattivo, come ad esempio il terminale, ma non si scarica quando si scrive su un file. – therainmaker

1

Probabilmente manchi a flush()std::cout. printf() ha un comportamento diverso a riguardo. Anche i buffer IO devono essere sincronizzati. Se si modifica il codice in

int main() { 
    ios_base::sync_with_stdio(true); // Synchronizing the IO buffers 
            // must be enabled 
    cin.tie(NULL);  

    for (int i = 0; i < 3; i++) { 
     cout << i << " "; 
     cout.flush(); // <<<<<<<<<< 
     printf("%d ", i); 
    } 

    cout << endl; 
    return 0; 
} 

dovrebbe comportarsi come previsto. Vedi la demo di lavoro here per favore.

+0

Produce la stessa uscita –

+0

@ReynaldoAguilar L'ho riparato. –

3

Se si desidera che l'uscita std::cout e printf da sincronia, è necessario utilizzare:

std::ios_base::sync_with_stdio(true); 

non

std::ios_base::sync_with_stdio(false); 

vederlo lavorare a http://ideone.com/7sgH2I.

5

Prova questa

cout << i << " " <<std::flush; 
    printf("%d ", i); 
    fflush(stdout); 
8

Per default C funzioni stdio printf, ecc e il C++ flussi io sono sincronizzati senso che possono essere usati in modo intercambiabile. All'inizio del codice hai rimosso la sincronizzazione con ios_base::sync_with_stdio(false) non sicuro se il tuo intento era di scrivere questo ios_base::sync_with_stdio(true) che sincronizza le due librerie io.