Qual é a diferença entre cout, cerr, clog of iostream header em c ++? Quando usar qual?

97

Eu tentei pesquisar a diferença entre cout, cerre clogna internet, mas não conseguiu encontrar uma resposta perfeita. Ainda não tenho certeza de quando usar qual. Alguém pode me explicar, através de programas simples e ilustrar uma situação perfeita de quando usar qual?

Visitei este site que mostra um pequeno programa no cerre clog, mas o output obtido ali também pode ser obtido usando cout. Então, estou confuso sobre o uso exato de cada um.

Arlene Batada
fonte
6
Cada um tem um fluxo reconhecido por computador, stdout, stdin(para cin), e stderrque ele usa por padrão. Eu acredito que clogé apenas cerrcom uma mudança de buffer.
Chris de

Respostas:

48

stdoute stderrsão fluxos diferentes, embora ambos se refiram à saída do console por padrão. Redirecionar (tubulação) um deles (por exemplo program.exe >out.txt) não afetaria o outro.

Geralmente, stdoutdeve ser usado para a saída real do programa, enquanto todas as informações e mensagens de erro devem ser impressas stderr, de modo que, se o usuário redirecionar a saída para um arquivo, as mensagens de informação ainda sejam impressas na tela e não no arquivo de saída.

riv
fonte
131

Geralmente você usa std::coutpara saída normal, std::cerrpara erros e std::clogpara "registro" (o que pode significar o que você quiser).

A principal diferença é que std::cerrnão é armazenado em buffer como os outros dois.


Em relação ao antigo C stdoute stderr, std::coutcorresponde a stdout, enquanto std::cerre std::clogambos correspondem a stderr(exceto que std::clogé armazenado em buffer).

Algum cara programador
fonte
Eu li que clogtambém dá saída para cerr. Então, com base nisso, qual você escolhe? Se clogfor normalmente para "registro", por que eu iria querer que isso fosse para o fluxo de erro? Os logs parecem mais "logs normais" (também conhecidos como cout) do que erros.
void.pointer
@ void.pointer Como eu disse em minha resposta, cerre clogusa a saída de "erro" padrão, mas clogé armazenado em buffer, o que pode ser o motivo pelo qual parece cout. Qual escolher para a saída de erro? Depende, eu acho, de mais razões do que eu posso listar e tem que ser decidido caso a caso.
Algum programador cara
3
o que você quer dizer com "buffer"?
simplename
5
@simplename A saída não é escrita diretamente, ela é armazenada em um buffer até que o buffer seja liberado . A saída para um arquivo ou terminal é historicamente lenta (terminais ou consoles ainda são lentos), escrever caractere por caractere é ineficaz, escrever um pedaço de bytes é muito mais eficaz.
Algum programador de
14

Fluxo de saída padrão (cout): cout é a instância da ostreamclasse. couté usado para produzir saída no dispositivo de saída padrão, que geralmente é a tela de exibição. Os dados que precisam ser exibidos na tela são inseridos no fluxo de saída padrão ( cout) usando o operador de inserção ( <<).

Fluxo de erro padrão sem buffer (cerr): cerr é o fluxo de erro padrão usado para gerar os erros. Esta também é uma instância da ostreamclasse. Como nãocerr está armazenado em buffer , é usado quando precisamos exibir a mensagem de erro imediatamente. Ele não tem nenhum buffer para armazenar a mensagem de erro e exibi-la posteriormente.

Fluxo de erro padrão com buffer (entupir): Esta também é uma instância da ostreamclasse e usada para exibir erros, mas ao contrário cerrdo erro é primeiro inserido em um buffer e armazenado no buffer até que não seja totalmente preenchido.

leitura adicional: basic-input-output-c

roottraveller
fonte
11

A diferença entre esses três fluxos é o buffer.

  1. Com cerr, a saída flushs
    • imediatamente (porque cerr não usa buffer).
  2. Com entupimento, a saída flushs
    • depois de terminar sua função atual.
    • chame explicitamente a função flush.
  3. Com cout, a saída flush
    • depois de ter chamado a qualquer fluxo de saída (cout, cerr, clog).
    • depois de terminar sua função atual.
    • chame explicitamente a função flush.

Verifique o código a seguir e execute DEBUG em 3 linhas: f (std :: clog), f (std :: cerr), f (std :: out) e, em seguida, abra 3 arquivos de saída para ver o que aconteceu. Você pode trocar essas 3 linhas para ver o que acontecerá.

#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";
}
Duc-Viet Ha
fonte
10
  • Use cout para a saída padrão.
  • Use cerr para mostrar os erros.
  • Use entupir para registrar.
David Vargas
fonte
6
Errado, cerr é mais lento do que cout por causa do não buffer! Assim como write vs printf
陳 力
4

De um documento padrão de rascunho C ++ 17:

30.4.3 Objetos de fluxo estreito [narrow.stream.objects]

istream cin;

1 O objeto cincontrola a entrada de um buffer de fluxo associado ao objeto stdin, declarado em <cstdio>(30.11.1).

2 Depois que o objeto ciné inicializado, cin.tie()retorna &cout. Caso contrário, seu estado é o mesmo exigido para basic_ios<char>::init(30.5.5.2).

ostream cout;

3 O objeto coutcontrola a saída para um buffer de fluxo associado ao objeto stdout, declarado em <cstdio>(30.11.1).

ostream cerr;

4 O objeto cerrcontrola a saída para um buffer de fluxo associado ao objeto stderr, declarado em <cstdio>(30.11.1).

5 Depois que o objeto cerré inicializado, cerr.flags() & unitbufé diferente de zero e cerr.tie()retorna &cout. Caso contrário, seu estado é o mesmo exigido para basic_ios<char>::init(30.5.5.2).

ostream clog;

6 O objeto clogcontrola a saída para um buffer de fluxo associado ao objeto stderr, declarado em <cstdio>(30.11.1).

Discussão...

coutescreve para stdout; cerre clogparastderr

A Saída Padrão ( stdout) destina-se a receber saída sem erro e sem diagnóstico do programa, como saída de processamento bem-sucedido que pode ser exibida para o usuário final ou transmitida para algum estágio de processamento posterior.

Erro padrão ( stderr) destina-se a saída de diagnóstico, como mensagens de aviso e erro que indicam que o programa não produziu ou pode não ter produzido a saída que o usuário espera. Essa entrada pode ser exibida para o usuário final, mesmo se os dados de saída forem canalizados para um estágio de processamento posterior.

cine cerrestão ligados acout

Ambos esvaziam coutantes de lidar com as operações de E / S. Isso garante que os prompts enviados para coutsejam visíveis antes dos blocos de programa para ler a entrada cin, e que a saída anterior coutseja liberada antes de escrever um erro cerr, o que mantém as mensagens em ordem cronológica de sua geração quando ambos são direcionados para o mesmo terminal / arquivo / etc ..

Isso contrasta com clog- se você escrever lá, ele não será armazenado em buffer e não estará vinculado a nada, portanto, armazenará em buffer quantidades decentes de registro antes de descarregar. Isso produz a maior taxa de transferência de mensagens, mas significa que as mensagens podem não ser rapidamente visíveis para um consumidor em potencial lendo o terminal ou seguindo o log.

Tony Delroy
fonte
1

Ambos cout e clog são armazenados em buffer, mas cerr não é armazenado em buffer e todos esses são objetos predefinidos que são instâncias da classe ostream. O uso básico desses três é cout é usado para entrada padrão, enquanto clog e cerr são usados ​​para mostrar erros. O ponto principal porque o cerr não está armazenado em buffer pode ser porque suponha que você tenha várias saídas no buffer e uma exceção de erro seja mencionada no código então você precisa mostrar esse erro imediatamente o que pode ser feito por cerr eficaz.

Por favor corrija-me se eu estiver errado.

Kashif Faraz Shamsi
fonte
-3

cout é geralmente usado para exibir algumas instruções na tela do usuário. ex-: cout << "Arlene Batada";

resultado:

Arlene Batada

Devendra Singh
fonte
Isso apenas menciona cout e não tenta compará-lo com cerr ou clog. OP sabe o que cout faz.
JPhi1618
Isso não fornece uma resposta para a pergunta. Assim que tiver reputação suficiente, você poderá comentar sobre qualquer postagem ; em vez disso, forneça respostas que não exijam esclarecimentos do autor da pergunta . - Da avaliação
kometen
@kometen isso tenta responder à pergunta, mesmo que seja uma resposta mal escrita. Deveria ter downvote em vez disso, downvotes são mais adequados para imprecisões técnicas.
Cristik