Neden printf ve cout kullanan bu kod beklenen çıktıya sahip değil?

Takip koduna sahibim:

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;
}

Bu kodun beklenen çıktısı:

0 0 1 1 2 2

ancak, bunun yerine, yazdırır:

0 1 2
0 1 2

Bu sorun GNU G ++ 4.9.2 derleyicisinde gerçekleşir.

12
Senkronizasyonu kendiniz kapattınız ve neden senkronize edilmediklerini sordunuz%)
katma yazar RiaD, kaynak
Senkronizasyonu kendiniz kapattınız ve neden senkronize edilmediklerini sordunuz%)
katma yazar RiaD, kaynak
Senkronizasyonu kendiniz kapattınız ve neden senkronize edilmediklerini sordunuz%)
katma yazar RiaD, kaynak
Ayrı tamponlar?
katma yazar Kerrek SB, kaynak
Ayrı tamponlar?
katma yazar Kerrek SB, kaynak
@KerrekSB kesinlikle bu ve sizden cevabı çalmak istemiyorum. printf ve cout, farklı zamanlarda yıkanmış ayrı tamponlar kullanır. Yukarıdaki kod durumunda, cout büyük olasılıkla aynı çizgide temizlendi ve çağrı sonunda printf temizlendi. Printf'deki boşluğu başka bir şeyle (_) değiştirin, göreceksiniz.
katma yazar IdeaHat, kaynak
@KerrekSB kesinlikle bu ve sizden cevabı çalmak istemiyorum. printf ve cout, farklı zamanlarda yıkanmış ayrı tamponlar kullanır. Yukarıdaki kod durumunda, cout büyük olasılıkla aynı çizgide temizlendi ve çağrı sonunda printf temizlendi. Printf'deki boşluğu başka bir şeyle (_) değiştirin, göreceksiniz.
katma yazar IdeaHat, kaynak
@KerrekSB kesinlikle bu ve sizden cevabı çalmak istemiyorum. printf ve cout, farklı zamanlarda yıkanmış ayrı tamponlar kullanır. Yukarıdaki kod durumunda, cout büyük olasılıkla aynı çizgide temizlendi ve çağrı sonunda printf temizlendi. Printf'deki boşluğu başka bir şeyle (_) değiştirin, göreceksiniz.
katma yazar IdeaHat, kaynak
fflush (stdout) ekle?
katma yazar Columbo, kaynak
fflush (stdout) ekle?
katma yazar Columbo, kaynak
fflush (stdout) ekle?
katma yazar Columbo, kaynak
Bu soru pek mantıklı değil; açıkça stdio ile standart akışların senkronize edilmediğini, neden senkronize edildiklerini sanıyorlar?
katma yazar T.C., kaynak
Bu soru pek mantıklı değil; açıkça stdio ile standart akışların senkronize edilmediğini, neden senkronize edildiklerini sanıyorlar?
katma yazar T.C., kaynak
Bu soru pek mantıklı değil; açıkça stdio ile standart akışların senkronize edilmediğini, neden senkronize edildiklerini sanıyorlar?
katma yazar T.C., kaynak
@ T.Ç. Tam olarak ne olup bittiğini biliyorsanız, soru gerçekten anlamlı değil, yani ios_base :: sync_with_stdio (false) çağrısının ne işe yaradığı. Belki de bu hat cin/cout kullanarak G/Ç işlemlerinin performansını iyileştirmek için burada.
katma yazar Reynaldo Aguilar, kaynak
@ T.Ç. Tam olarak ne olup bittiğini biliyorsanız, soru gerçekten anlamlı değil, yani ios_base :: sync_with_stdio (false) çağrısının ne işe yaradığı. Belki de bu hat cin/cout kullanarak G/Ç işlemlerinin performansını iyileştirmek için burada.
katma yazar Reynaldo Aguilar, kaynak
@ T.Ç. Tam olarak ne olup bittiğini biliyorsanız, soru gerçekten anlamlı değil, yani ios_base :: sync_with_stdio (false) çağrısının ne işe yaradığı. Belki de bu hat cin/cout kullanarak G/Ç işlemlerinin performansını iyileştirmek için burada.
katma yazar Reynaldo Aguilar, kaynak

15 cevap

Bunun olası bir açıklaması cout ve printf 'in ayrı tamponlar kullanmasıdır. cout terminal ekranında, endl komutu kullanılarak temizlendiğinde veya arabellek dolduğunda (genellikle 512 bayt) çıkar.

printf hakkında emin değilim (bu nedenle hatalıysam beni düzeltmekten çekinmeyin), ancak benzer bir davranış izler. Öyleyse, programın sonunda, her iki tamponun yıkandığı ve böylece gördüğünüz çıktının elde edildiğidir.

Kodu makinemde (GCC 4.8.1) aşağıdaki gibi bir değişiklikle birlikte çalıştırdım

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

Gözlemlediğim çıktı 0 1 2 0 idi. 1. 2. ki bu printf'in benim durumumda ilk kez temizlendiğini gösteriyor. Tasarımla mı (standartta herhangi bir yerde bahsedilir) veya içeriğe bağlı olup olmadığı hakkında hiçbir fikrim yok.

10
katma
Oldukça emin olmak gerekirse cout da yeni satırlar için temizlenir, ancak çoğu yayın istemez.
katma yazar Mooing Duck, kaynak
@MooingDuck: Okuduklarımdan itibaren, cout , terminal gibi etkileşimli bir cihaza çıktığında yeni satırlar için temizlenir, ancak bir dosyaya yazarken temizlemez.
katma yazar therainmaker, kaynak

Bunun olası bir açıklaması cout ve printf 'in ayrı tamponlar kullanmasıdır. cout terminal ekranında, endl komutu kullanılarak temizlendiğinde veya arabellek dolduğunda (genellikle 512 bayt) çıkar.

printf hakkında emin değilim (bu nedenle hatalıysam beni düzeltmekten çekinmeyin), ancak benzer bir davranış izler. Öyleyse, programın sonunda, her iki tamponun yıkandığı ve böylece gördüğünüz çıktının elde edildiğidir.

Kodu makinemde (GCC 4.8.1) aşağıdaki gibi bir değişiklikle birlikte çalıştırdım

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

Gözlemlediğim çıktı 0 1 2 0 idi. 1. 2. ki bu printf'in benim durumumda ilk kez temizlendiğini gösteriyor. Tasarımla mı (standartta herhangi bir yerde bahsedilir) veya içeriğe bağlı olup olmadığı hakkında hiçbir fikrim yok.

10
katma
Oldukça emin olmak gerekirse cout da yeni satırlar için temizlenir, ancak çoğu yayın istemez.
katma yazar Mooing Duck, kaynak
@MooingDuck: Okuduklarımdan itibaren, cout , terminal gibi etkileşimli bir cihaza çıktığında yeni satırlar için temizlenir, ancak bir dosyaya yazarken temizlemez.
katma yazar therainmaker, kaynak

Bunun olası bir açıklaması cout ve printf 'in ayrı tamponlar kullanmasıdır. cout terminal ekranında, endl komutu kullanılarak temizlendiğinde veya arabellek dolduğunda (genellikle 512 bayt) çıkar.

printf hakkında emin değilim (bu nedenle hatalıysam beni düzeltmekten çekinmeyin), ancak benzer bir davranış izler. Öyleyse, programın sonunda, her iki tamponun yıkandığı ve böylece gördüğünüz çıktının elde edildiğidir.

Kodu makinemde (GCC 4.8.1) aşağıdaki gibi bir değişiklikle birlikte çalıştırdım

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

Gözlemlediğim çıktı 0 1 2 0 idi. 1. 2. ki bu printf'in benim durumumda ilk kez temizlendiğini gösteriyor. Tasarımla mı (standartta herhangi bir yerde bahsedilir) veya içeriğe bağlı olup olmadığı hakkında hiçbir fikrim yok.

10
katma
Oldukça emin olmak gerekirse cout da yeni satırlar için temizlenir, ancak çoğu yayın istemez.
katma yazar Mooing Duck, kaynak
@MooingDuck: Okuduklarımdan itibaren, cout , terminal gibi etkileşimli bir cihaza çıktığında yeni satırlar için temizlenir, ancak bir dosyaya yazarken temizlemez.
katma yazar therainmaker, kaynak

Varsayılan olarak, C stdio printf, vb. İşlevlerini yerine getirir ve C ++ io akışları senkronizedir, yani bunlar birbirlerinin yerine kullanılabilir. Kodunuzun başında senkronizasyonu ios_base :: sync_with_stdio (false) ile kaldırdınız, asıl amacınızın bu ios_base :: sync_with_stdio (true) yazıp yazmadığından emin değilsiniz. Bu iki io ​​kütüphanesini senkronize eder.

8
katma

Varsayılan olarak, C stdio printf, vb. İşlevlerini yerine getirir ve C ++ io akışları senkronizedir, yani bunlar birbirlerinin yerine kullanılabilir. Kodunuzun başında senkronizasyonu ios_base :: sync_with_stdio (false) ile kaldırdınız, asıl amacınızın bu ios_base :: sync_with_stdio (true) yazıp yazmadığından emin değilsiniz. Bu iki io ​​kütüphanesini senkronize eder.

8
katma

Varsayılan olarak, C stdio printf, vb. İşlevlerini yerine getirir ve C ++ io akışları senkronizedir, yani bunlar birbirlerinin yerine kullanılabilir. Kodunuzun başında senkronizasyonu ios_base :: sync_with_stdio (false) ile kaldırdınız, asıl amacınızın bu ios_base :: sync_with_stdio (true) yazıp yazmadığından emin değilsiniz. Bu iki io ​​kütüphanesini senkronize eder.

8
katma

Bunu dene

    cout << i << " " <
5
katma

Bunu dene

    cout << i << " " <
5
katma

Bunu dene

    cout << i << " " <
5
katma

std :: cout ve printf çıkışının senkronize edilmesini istiyorsanız, kullanmanız gerekir:

std::ios_base::sync_with_stdio(true);

değil

std::ios_base::sync_with_stdio(false);

http://ideone.com/7sgH2I adresinde çalıştığını görün.

3
katma

std :: cout ve printf çıkışının senkronize edilmesini istiyorsanız, kullanmanız gerekir:

std::ios_base::sync_with_stdio(true);

değil

std::ios_base::sync_with_stdio(false);

http://ideone.com/7sgH2I adresinde çalıştığını görün.

3
katma

std :: cout ve printf çıkışının senkronize edilmesini istiyorsanız, kullanmanız gerekir:

std::ios_base::sync_with_stdio(true);

değil

std::ios_base::sync_with_stdio(false);

http://ideone.com/7sgH2I adresinde çalıştığını görün.

3
katma

Muhtemelen flush() std :: cout 'u özlüyorsunuz. printf() bu konuda farklı bir davranışa sahiptir. Ayrıca GÇ arabellekleri senkronize edilmelidir. Kodunuzu olarak değiştirirseniz,

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;
}

beklediğiniz gibi davranmalıdır. Lütfen buradaki çalışma demosuna bakın.

1
katma
@ReynaldoAguilar Bunu düzelttim.
katma yazar πάντα ῥεῖ, kaynak
Aynı çıktıyı üretir
katma yazar Reynaldo Aguilar, kaynak

Muhtemelen flush() std :: cout 'u özlüyorsunuz. printf() bu konuda farklı bir davranışa sahiptir. Ayrıca GÇ arabellekleri senkronize edilmelidir. Kodunuzu olarak değiştirirseniz,

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;
}

beklediğiniz gibi davranmalıdır. Lütfen buradaki çalışma demosuna bakın.

1
katma
@ReynaldoAguilar Bunu düzelttim.
katma yazar πάντα ῥεῖ, kaynak
Aynı çıktıyı üretir
katma yazar Reynaldo Aguilar, kaynak

Muhtemelen flush() std :: cout 'u özlüyorsunuz. printf() bu konuda farklı bir davranışa sahiptir. Ayrıca GÇ arabellekleri senkronize edilmelidir. Kodunuzu olarak değiştirirseniz,

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;
}

beklediğiniz gibi davranmalıdır. Lütfen buradaki çalışma demosuna bakın.

1
katma
@ReynaldoAguilar Bunu düzelttim.
katma yazar πάντα ῥεῖ, kaynak
Aynı çıktıyı üretir
katma yazar Reynaldo Aguilar, kaynak