C ++ 'da cout, Cerr, clog of iostream header arasındaki fark nedir? Hangisi ne zaman kullanılır?


104

Ben arasındaki farkı araştırma çalıştı cout, cerrve cloginternette ama mükemmel bir cevap bulamadık. Hangisini ne zaman kullanacağım konusunda hala net değilim. Biri bana basit programlarla açıklayabilir ve hangisinin ne zaman kullanılacağına dair mükemmel bir durumu örnekleyebilir mi?

Ziyaret ettim bu siteyi üzerinde küçük bir program gösterir cerrve clogaynı zamanda kullanılarak elde edilebilir üzerinde çıkış elde cout. Yani, her birinin kesin kullanımı konusunda kafam karıştı.


6
Her birinin stdout, stdin(için cin) ve stderrvarsayılan olarak kullandığı , bilgisayar tarafından tanınan bir akışı vardır . Sanırım clogsadece cerrgeçici bir değişiklikle.
chris

Yanıtlar:


53

stdoutve stderrher ikisi de varsayılan olarak konsol çıktısına atıfta bulunsalar da farklı akışlardır. Bunlardan birinin (örneğin program.exe >out.txt) yeniden yönlendirilmesi (borulama) diğerini etkilemeyecektir.

Genel olarak, stdoutgerçek program çıktısı için kullanılmalıdır, ancak tüm bilgi ve hata mesajlarının yazdırılması gerekir stderr, böylece kullanıcı çıktıyı bir dosyaya yönlendirirse, bilgi mesajları çıktı dosyasına değil ekrana yazdırılır.


133

Genellikle std::coutnormal çıktı std::cerriçin, hatalar için ve std::clog"günlüğe kaydetme" için kullanırsınız (bu, ne anlama geliyorsa onu ifade edebilir).

En büyük fark, std::cerrdiğer ikisi gibi tamponlanmamış olmasıdır.


Eski C stdoutile ilişkili olarak ve stderr, std::coutkarşılık gelir stdout, while std::cerrve std::clogher ikisi de karşılık gelir stderr( std::clogtamponlu olması dışında ).


Bunun clogda çıktılarını okudum cerr. Peki buna dayanarak hangisini seçersiniz? Eğer clogbunu hata akımına gitmek istemesi için, normalde "günlük" içindir? Günlükler cout, hatalardan çok "normal günlükler" (aka ) gibi görünür .
void.pointer

@ void.pointer benim cevap dediği gibi, hem cerrve clogstandart "hata" çıktı kullanır, ancak clogdaha fazla gibi görünüyor neden olabilir hangi tamponlanana cout. Hata çıktısı için hangisi seçilir? Sanırım listeleyebileceğimden daha fazla nedene bağlı ve duruma göre karar verilmesi gerekiyor.
Bir programcı dostum

3
"Tamponlu" ile ne demek istiyorsun?
basit ad

6
@simplename Çıktı doğrudan yazılmaz , tampon temizlenene kadar bir tamponda saklanır . Bir dosyaya veya terminale çıkış tarihsel olarak yavaştır (terminaller veya konsollar hala yavaştır), karakter karakter yazmak etkisizdir, bir yığın bayt yazmak çok daha etkilidir.
Bir programcı dostum

17

Standart çıktı akışı (cout): sınıfın coutörneğidir ostream. coutgenellikle görüntü ekranı olan standart çıktı aygıtında çıktı üretmek için kullanılır. Ekranda görüntülenmesi gereken veriler cout, ekleme operatörü ( <<) kullanılarak standart çıkış akışına ( ) eklenir .

Arabelleğe alınmamış standart hata akışı (Cerr): cerr Hataların çıktısını almak için kullanılan standart hata akışıdır. Bu aynı zamanda ostreamsınıfın bir örneğidir . As cerrolan un-tamponlu hemen hata mesajı göstermek için gerektiğinde kullanıldığı böylece. Hata mesajını saklamak ve daha sonra görüntülemek için herhangi bir ara belleğe sahip değildir.

Tamponlanmış standart hata akışı (tıkanma): Bu aynı zamanda bir ostreamsınıf örneğidir ve hataları görüntülemek için kullanılır, ancak cerrhatanın aksine önce bir tampona eklenir ve tamamen doldurulana kadar arabellekte saklanır.

daha fazla okuma: temel-girdi-çıktı-c


2
until it is not fully filled.- bu söylememeli until it IS fully filledmi?
Gabriel Staples

11

Bu 3 akışın farkı arabelleğe almaktır.

  1. Cerr ile çıktı temizler
    • hemen (çünkü Cerrah tampon kullanmaz).
  2. Tıkanma ile çıktı temizler
    • mevcut işlevinizi bitirdikten sonra.
    • flush işlevini açıkça çağırın.
  3. Cout ile çıktı yıkar
    • herhangi bir çıktı akışına (cout, cer, clog) çağrı yaptıktan sonra.
    • mevcut işlevinizi bitirdikten sonra.
    • flush işlevini açıkça çağırın.

Lütfen aşağıdaki kodu kontrol edin ve 3 satırdan DEBUG'ı çalıştırın: f (std :: clog), f (std :: cerr), f (std :: out), sonra ne olduğunu görmek için 3 çıktı dosyası açın. Ne olacağını görmek için bu 3 satırı değiştirebilirsiniz.

#include <iostream>
#include <fstream>
#include <string>

void f(std::ostream &os)
{
    std::cin.clear(); // clear EOF flags
    std::cin.seekg(0, std::cin.beg); // seek to begin

    std::string line;
    while(std::getline(std::cin, line))   //input from the file in.txt
        os << line << "\n";   //output to the file out.txt
}

void test()
{
    std::ifstream in("in.txt");
    std::ofstream out("out.txt"), err("err.txt"), log("log.txt");
    std::streambuf *cinbuf = std::cin.rdbuf(), *coutbuf = std::cout.rdbuf(), *cerrbuf = std::cerr.rdbuf(),
                    *clogbuf = std::clog.rdbuf();

    std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!
    std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!
    std::cerr.rdbuf(err.rdbuf());
    std::clog.rdbuf(log.rdbuf());


    f(std::clog);
    f(std::cerr);
    f(std::cout);

    std::cin.rdbuf(cinbuf);
    std::cout.rdbuf(coutbuf);
    std::cerr.rdbuf(cerrbuf);
    std::clog.rdbuf(clogbuf);
}

int main()
{
    test();
    std::cout << "123";
}

10
  • Standart çıktı için cout kullanın .
  • Hataları göstermek için cerrah'ı kullanın .
  • Günlük kaydı için tıkanıklık kullanın .

6
Yanlış, cerrah, tampon olmadığı için cout'tan daha yavaş! Tıpkı write vs printf gibi
陳 力

5

Taslak bir C ++ 17 standart belgesinden:

30.4.3 Dar akış nesneleri [dar.stream.objects]

istream cin;

1 cinNesne stdin, <cstdio>(30.11.1) 'de açıklanan nesne ile ilişkili bir akış arabelleğinden gelen girdiyi kontrol eder .

2 Nesne cinbaşlatıldıktan sonra cin.tie()geri döner &cout. Aksi takdirde durumu basic_ios<char>::init(30.5.5.2) için gerekli olanla aynıdır .

ostream cout;

3 coutNesne stdout, <cstdio>(30.11.1) 'de açıklanan nesne ile ilişkili bir akış arabelleğine çıktıyı kontrol eder .

ostream cerr;

4 cerrNesne stderr, <cstdio>(30.11.1) 'de açıklanan nesne ile ilişkili bir akış arabelleğine çıktıyı kontrol eder .

5 Nesne cerrbaşlatıldıktan sonra cerr.flags() & unitbufsıfırdan farklıdır ve cerr.tie()geri döner &cout. Aksi takdirde durumu basic_ios<char>::init(30.5.5.2) için gerekli olanla aynıdır .

ostream clog;

6 clogNesne stderr, <cstdio>(30.11.1) 'de açıklanan nesneyle ilişkili bir akış arabelleğine çıktıyı kontrol eder .

Tartışma...

coutyazıyor stdout; cerrve cloghiçstderr

Standart Çıkış ( stdout), programdan, son kullanıcıya gösterilebilen veya başka bir işleme aşamasına aktarılabilen başarılı işlemden elde edilen çıktı gibi hatasız, tanısal olmayan çıktı almayı amaçlamaktadır.

Standart Hata ( stderr), programın kullanıcının bekleyebileceği çıktıyı üretmediğini veya üretmediğini belirten uyarı ve hata mesajları gibi tanılama çıktıları için tasarlanmıştır. Bu girdi, çıktı verileri başka bir işlem aşamasına aktarılsa bile son kullanıcıya görüntülenebilir.

cinve cerrbağlıcout

Her ikisi de coutG / Ç işlemlerini kendileri yapmadan önce yıkar . Bu, gönderilen komutların coutprogram bloklarından önce okunmasını sağlar cinve önceki çıktının, coutbir hata yazılmadan önce yıkanmasını cerrsağlar; vb..

Bu, clog- eğer orada yazarsanız, arabelleğe alınmaz ve hiçbir şeye bağlı değildir, bu nedenle, temizlemeden önce makul büyüklükteki günlükleri arabelleğe alacaktır. Bu, mesajların en yüksek verimini verir, ancak mesajların, uçbirimi okuyan veya günlüğü takip eden bir tüketici tarafından hızlı bir şekilde görülemeyebileceği anlamına gelir.


1

Hem cout ve yapışmasına neden tamponlu ancak CERR arabelleğe olup, bu her sınıf ostream örnekleri olan nesneler önceden tanımlanmıştır. Bu üç temel kullanımı vardır cout ise standart giriş için kullanılan yapışmasına neden ve CERR hataları göstermek için kullanılır. Cerrah'ın arabelleğe alınmamasının ana noktası , arabellekte birkaç çıktıya sahip olduğunuzu ve kodda bir hata istisnasından bahsedildiğini varsaymak olabilir, bu durumda cerrah tarafından etkin bir şekilde yapılabilen bu hatayı hemen görüntülemeniz gerekir .

Yanlışım varsa lütfen düzelt.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.