web-dev-qa-db-fra.com

Quelle est la différence entre cout, cerr et obstruction d'en-tête iostream en c ++? Quand utiliser lequel?

J'ai essayé de rechercher la différence entre cout, cerr et clog sur Internet, mais je n'ai pas trouvé de réponse parfaite. Je ne sais toujours pas quand utiliser lequel. Est-ce que n'importe qui peut m'expliquer, par des programmes simples et illustrer une situation parfaite sur quand utiliser lequel?

J'ai visité ce site qui montre un petit programme sur cerr et clog, mais la sortie obtenue là-bas peut également être obtenue avec cout. Donc, je suis confus sur l'utilisation exacte de chacun.

78
Arlene Batada

stdout et stderr sont des flux différents, même s'ils font tous deux référence à la sortie de la console par défaut. Rediriger (canaliser) l’un d’eux (par exemple program.exe >out.txt) n'affecterait pas l'autre.

En règle générale, stdout doit être utilisé pour la sortie du programme, tandis que tous les messages d’information et d’erreur doivent être imprimés sur stderr. Ainsi, si l’utilisateur redirige la sortie vers un fichier, les messages d’information sont toujours imprimés. l'écran et non dans le fichier de sortie.

43
riv

Généralement, vous utilisez std::cout pour une sortie normale, std::cerr pour les erreurs et std::clog pour "journalisation" (ce qui peut vouloir dire ce que vous voulez dire).

La principale différence est que std::cerr n'est pas tamponné comme les deux autres.


En relation avec l'ancien C stdout et stderr, std::cout correspond à stdout, tandis que std::cerr et std::clog _ les deux correspondent à stderr (sauf que std::clog est tamponné).

114
  • Utilisez cout pour la sortie standard.
  • Utilisez cerr pour afficher les erreurs.
  • Utilisez obstruer pour la journalisation.
8
David Vargas

Flux de sortie standard (cout): cout est l'instance de la classe ostream. cout est utilisé pour produire une sortie sur le périphérique de sortie standard qui est généralement l'écran d'affichage. Les données nécessaires pour être affichées à l'écran sont insérées dans le flux de sortie standard (cout) à l'aide de l'opérateur d'insertion (<<).

Flux d'erreur standard sans mémoire tampon (cerr): cerr est le flux d'erreur standard utilisé pour générer les erreurs. C'est aussi une instance de la classe ostream. Comme cerr est non tamponné , il est donc utilisé lorsque nous devons afficher le message d'erreur immédiatement. Il n'a pas de tampon pour stocker le message d'erreur et l'afficher plus tard.

Flux d'erreur standard tamponné (encrassement): Il s'agit également d'une instance de la classe ostream utilisée pour afficher les erreurs, mais contrairement à cerr l'erreur est d'abord insérée dans un tampon et est stockée dans le tampon jusqu'à ce qu'elle ne soit pas complètement remplie.

lectures supplémentaires: basic-input-output-c

8
roottraveller

La différence entre ces 3 flux est la mise en mémoire tampon.

  1. Avec cerr, la sortie efface
    • immédiatement (car cerr n’utilise pas de tampon).
  2. Avec obstruction, la sortie affleure
    • après avoir terminé votre fonction actuelle.
    • appeler explicitement la fonction flush.
  3. Avec cout, la sortie affleure
    • après avoir appelé tous les flux de sortie (cout, cerr, obstruction).
    • après avoir terminé votre fonction actuelle.
    • appeler explicitement la fonction flush.

Veuillez vérifier le code suivant et exécuter DEBUG sur 3 lignes: f (std :: clog), f (std :: cerr), f (std :: out), puis ouvrez 3 fichiers de sortie pour voir ce qui s'est passé. Vous pouvez échanger ces 3 lignes pour voir ce qui se passera.

#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";
}
5
Duc-Viet Ha

A partir d'un projet de document standard C++ 17:

30.4.3 Objets à flux étroit [narrow.stream.objects]

istream cin;

1 L'objet cin contrôle les entrées d'un tampon de flux associé à l'objet stdin, déclaré dans <cstdio> (30.11.1).

2 Une fois l'objet cin initialisé, cin.tie() renvoie &cout. Son état est par ailleurs identique à celui requis pour basic_ios<char>::init (30.5.5.2).

ostream cout;

3 L'objet cout contrôle la sortie dans un tampon de flux associé à l'objet stdout, déclaré dans <cstdio> (30.11.1).

ostream cerr;

4 L'objet cerr contrôle la sortie dans un tampon de flux associé à l'objet stderr, déclaré dans <cstdio> (30.11.1).

5 Une fois l'objet cerr initialisé, cerr.flags() & unitbuf n'est pas nul et cerr.tie() renvoie &cout. Son état est par ailleurs identique à celui requis pour basic_ios<char>::init (30.5.5.2).

ostream clog;

6 L'objet clog contrôle la sortie dans un tampon de flux associé à l'objet stderr, déclaré dans <cstdio> (30.11.1).

Discussion...

cout écrit dans stdout; cerr et clog dans stderr

La sortie standard (stdout) est destinée à recevoir une sortie sans erreur ni diagnostic de la part du programme, telle qu'une sortie d'un traitement réussi pouvant être affichée à l'utilisateur final ou diffusée à un stade ultérieur du traitement.

L'erreur standard (stderr) est conçue pour les résultats de diagnostic, tels que les messages d'avertissement et d'erreur indiquant que le programme n'a pas généré ou n'a peut-être pas généré les résultats attendus par l'utilisateur. Cette entrée peut être affichée pour l'utilisateur final même si les données de sortie sont acheminées vers une autre étape de traitement.

cin et cerr sont liés à cout

Ils effacent tous les deux cout avant de manipuler eux-mêmes les opérations d'E/S. Cela garantit que les invites envoyées à cout sont visibles avant que le programme ne lise l'entrée de cin, et que la sortie précédente vers cout soit vidée avant l'écriture d'une erreur via cerr, qui conserve les messages dans l’ordre chronologique de leur génération lorsque les deux sont dirigés vers le même terminal/fichier/etc.

Ceci contraste avec clog - si vous écrivez ici, il ne sera ni mis en mémoire tampon, ni lié à quoi que ce soit, il va donc mettre en mémoire tampon une quantité de journalisation de taille décente avant le vidage. Cela donne le débit de messages le plus élevé, mais signifie que les messages peuvent ne pas être rapidement visibles par un consommateur potentiel qui lit le terminal ou met le journal à la queue.

3
Tony Delroy

cout et obstruction sont tous deux tamponnés mais cerr n'est pas tamponné et tous sont des objets prédéfinis qui sont des instances de la classe ostream. L'utilisation de base de ces trois méthodes est cout est utilisé pour l'entrée standard, alors que obstruction et cerr est utilisé pour afficher les erreurs. La raison principale pour laquelle cerr est sans tampon est peut-être parce que vous avez plusieurs sorties dans le tampon et qu’une exception d’erreur est mentionnée dans le code, vous devez alors afficher cette erreur immédiatement, ce qui peut être fait par cerr efficacement.

S'il vous plait corrigez moi si je me trompe.

1
Kashif Faraz Shamsi