C ++에서 iostream 헤더의 cout, cerr, clog의 차이점은 무엇입니까? 어느 것을 사용해야합니까?


97

나는 사이의 차이를 연구 노력 cout, cerr그리고 clog인터넷에 있지만 완벽한 해답을 찾을 수 없습니다. 언제 어떤 것을 사용해야할지 아직 명확하지 않습니다. 누구든지 간단한 프로그램을 통해 나에게 설명하고 어떤 것을 사용해야 할 때 완벽한 상황을 설명 할 수 있습니까?

나는 방문 이 사이트 에 작은 프로그램을 보여줍니다 cerrclog뿐만 아니라 사용하여 얻을 수있다 이상의 출력을 얻을 cout. 그래서 나는 각각의 정확한 사용에 대해 혼란 스럽습니다.


6
각각에는 컴퓨터에서 인식하는 스트림 인 stdout, stdin(용 cin)이 stderr있으며 기본적으로 사용됩니다. 저는 믿습니다 clog그냥 cerr버퍼링 변화.
chris

답변:


48

stdout그리고 stderr둘 다 기본적으로 콘솔 출력을 참조하더라도, 다른 스트림입니다. 그들 중 하나를 리디렉션 (파이핑)해도 (예 :) 다른 하나 program.exe >out.txt에는 영향을주지 않습니다.

일반적으로 stdout실제 프로그램 출력에 사용되어야하며 모든 정보 및 오류 메시지는에 인쇄되어야합니다 stderr. 그래야 사용자가 출력을 파일로 리디렉션하는 경우 정보 메시지가 출력 파일이 아닌 화면에 계속 인쇄됩니다.


131

일반적으로 std::cout일반 출력, std::cerr오류 및 std::clog"로깅"(원하는대로 의미 할 수 있음)에 사용합니다.

가장 큰 차이점은 std::cerr다른 두 가지처럼 버퍼링되지 않는다는 것입니다.


이전 C stdout와 관련하여 및 stderr,에 std::cout해당하는 stdout반면 std::cerrstd::clog둘 다에 해당합니다 stderr( std::clog버퍼링 된 경우 제외 ).


나는 clog또한 cerr. 그래서 그것을 바탕으로 어떤 것을 선택합니까? 경우는 clog내가 그 오류 스트림에 가고 싶은 이유, 일반적으로 "로깅"입니다? 로그는 cout오류보다 "일반 로그"(일명 ) 처럼 보입니다 .
void.pointer

@ void.pointer 내가 내 대답에 말했듯이, 모두 cerrclog표준 "오류"출력을 사용하지만 clog더처럼 보인다 이유가 될 수있는 버퍼링된다 cout. 오류 출력을 위해 어느 것을 선택해야합니까? 내가 목록에 올릴 수있는 것보다 더 많은 이유에 따라 다르며 케이스마다 결정되어야합니다.
일부 프로그래머 친구

3
"버퍼링 됨"이란 무엇을 의미합니까?
simplename

5
@simplename 출력은 직접 작성되지 않으며 버퍼가 플러시 될 때까지 버퍼에 저장됩니다 . 파일이나 터미널로의 출력은 역사적으로 느리고 (터미널이나 콘솔은 여전히 ​​느립니다), 문자 단위로 쓰는 것은 효과가 없으며, 바이트 덩어리를 쓰는 것이 훨씬 더 효과적입니다.
일부 프로그래머 친구

14

표준 출력 스트림 (cout) : 클래스 cout의 인스턴스입니다 ostream. cout일반적으로 디스플레이 화면 인 표준 출력 장치에서 출력을 생성하는 데 사용됩니다. 화면에 표시하는 데 필요한 데이터 cout는 삽입 연산자 ( <<)를 사용하여 표준 출력 스트림 ( )에 삽입 됩니다.

버퍼링되지 않은 표준 오류 스트림 (cerr) : cerr 오류를 출력하는 데 사용되는 표준 오류 스트림입니다. 이것은 또한 ostream클래스 의 인스턴스입니다 . 마찬가지로 cerr입니다 않은 버퍼 우리는 즉시 오류 메시지를 표시 할 때 사용되도록. 오류 메시지를 저장하고 나중에 표시 할 버퍼가 없습니다.

버퍼링 된 표준 오류 스트림 (clog) : 이것은 또한 ostream클래스 의 인스턴스이며 오류를 표시하는 데 사용되지만 오류와 cerr는 달리 먼저 버퍼에 삽입되고 완전히 채워지지 않을 때까지 버퍼에 저장됩니다.

추가 읽기 : 기본 입력 출력 c


11

이 세 가지 스트림의 차이점은 버퍼링입니다.

  1. cerr을 사용하면 출력이 플러시됩니다.
    • 즉시 (cerr이 버퍼를 사용하지 않기 때문에).
  2. 막힘으로 출력이 플러시됩니다.
    • 현재 기능을 마친 후.
    • flush 함수를 명시 적으로 호출합니다.
  3. cout을 사용하면 출력이 플러시됩니다.
    • 출력 스트림 (cout, cerr, clog)을 호출 한 후.
    • 현재 기능을 마친 후.
    • flush 함수를 명시 적으로 호출합니다.

다음 코드를 확인하고 f (std :: clog), f (std :: cerr), f (std :: out)의 3 줄을 통해 DEBUG를 실행 한 다음 3 개의 출력 파일을 열어 무슨 일이 발생했는지 확인하십시오. 이 세 줄을 바꿔서 무슨 일이 일어나는지 볼 수 있습니다.

#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
  • 표준 출력에는 cout 을 사용하십시오 .
  • 오류를 표시 하려면 cerr 을 사용하십시오 .
  • 로깅을 위해 clog 를 사용하십시오 .

6
잘못되었습니다. cerr은 버퍼가 아니기 때문에 cout보다 느립니다! 그냥 printf와 대 쓰기와 같은
陳力

4

초안 C ++ 17 표준 문서에서 :

30.4.3 좁은 스트림 객체 [narrow.stream.objects]

istream cin;

1 객체 cin는 (30.11.1) stdin에서 선언 된 객체와 관련된 스트림 버퍼의 입력을 제어합니다 <cstdio>.

2 객체 cin가 초기화 된 후를 cin.tie()반환합니다 &cout. 그렇지 않으면 상태는 basic_ios<char>::init(30.5.5.2)에 필요한 것과 동일합니다 .

ostream cout;

3 객체 cout는 (30.11.1) stdout에서 선언 된 객체와 관련된 스트림 버퍼에 대한 출력을 제어합니다 <cstdio>.

ostream cerr;

4 객체 cerr는 다음 stderr에서 선언 된 객체와 관련된 스트림 버퍼에 대한 출력을 제어합니다 .<cstdio> (30.11.1) .

5 객체 cerr가 초기화 된 후 cerr.flags() & unitbuf0이 아니고를 cerr.tie()반환합니다 &cout. 그렇지 않으면 상태는 basic_ios<char>::init(30.5.5.2)에 필요한 것과 동일합니다 .

ostream clog;

6 개체 clog 는 (30.11.1) stderr에서 선언 된 객체와 관련된 스트림 버퍼에 대한 출력을 제어합니다 <cstdio>.

토론...

cout에 씁니다 stdout;cerrclogstderr

표준 출력 ( stdout)은 최종 사용자에게 표시되거나 일부 추가 처리 단계로 스트리밍 될 수있는 성공적인 처리의 출력과 같이 프로그램에서 오류가없는 비 진단 출력을 수신하기위한 것입니다.

표준 에러 (stderr )는 프로그램이 사용자가 예상 할 수있는 출력을 생성하지 않았거나 생성하지 않았 음을 나타내는 경고 및 오류 메시지와 같은 진단 출력을위한 것입니다. 이 입력은 출력 데이터가 추가 처리 단계로 파이프되는 경우에도 최종 사용자에게 표시 될 수 있습니다.

cin그리고 cerr에 묶여있다cout

둘 다 coutI / O 작업을 처리하기 전에 플러시 됩니다. 이렇게하면에 전송 된 프롬프트 cout가 프로그램이에서 입력을 읽는 것을 차단하기 전에 표시 cin되고 이전 출력이를 cout통해 오류를 쓰기 전에 플러시됩니다.cerr 되도록하여 둘 다 동일한 터미널 / 파일 / 기타..

이것은 clog-당신이 거기에 쓰면 버퍼링되지 않고 아무것도 연결되지 않으므로 플러시하기 전에 적절한 크기의 로깅을 버퍼링합니다. 이렇게하면 메시지 처리량이 가장 높지만 터미널을 읽거나 로그를 추적하려는 소비자에게 메시지가 빠르게 표시되지 않을 수 있습니다.


1

cout을 하고 막힘이 버퍼링되지만 cerr는 않은 버퍼이며,이 모든 클래스 ostream에의 인스턴스 인 객체를 미리 정의되어 있습니다. 이 세 가지의 기본 사용은 cout 이 표준 입력에 사용되는 반면 clogcerr 은 오류를 표시하는 데 사용됩니다. cerr 이 버퍼링되지 않은 이유 는 버퍼에 여러 출력이 있고 코드에 오류 예외가 언급되어 있다고 가정하면 해당 오류를 즉시 표시해야하므로 cerr에 의해 수행 될 수 있습니다. 효과적으로 .

내가 틀렸다면 나를 바로 잡으십시오.


-3

cout은 일반적으로 사용자 화면에 일부 명령문을 표시하는 데 사용됩니다. ex- : cout << "Arlene Batada";

산출:

알린 바 타다


이것은 cout만을 언급하고 cerr 또는 clog와 비교하려고 시도하지 않습니다. OP는 cout이 무엇을하는지 알고 있습니다.
JPhi1618

이것은 질문에 대한 답을 제공하지 않습니다. 평판 이 충분 하면 모든 게시물댓글 수 있습니다 . 대신 질문자의 설명이 필요하지 않은 답변을 제공하세요 . - 리뷰에서
kometen

@kometen 이것은 잘못 작성된 답변이더라도 질문에 대한 답변을 시도합니다. 대신에 반대표를 던 졌어 야한다면 반대표는 기술적 부정확성에 더 적합합니다.
Cristik
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.