C ++ :“std :: endl”vs“\ n”


569

많은 C ++ 서적에는 다음과 같은 예제 코드가 포함되어 있습니다.

std::cout << "Test line" << std::endl;

... 그래서 항상 그렇게했습니다. 그러나 대신 다음과 같이 일하는 개발자의 많은 코드를 보았습니다.

std::cout << "Test line\n";

다른 것을 선호하는 기술적 이유가 있습니까, 아니면 코딩 스타일의 문제입니까?




25
@derobert 이것은 하나가 다른 것보다 나이가 많다
Kira

3
@HediNaily 사실입니다. 그러나 다른 하나의 대답은 나에게 약간 더 나았습니다. 그래서 나는 그 방법으로 그렇게하기로 결정했습니다. 또한, 다른 하나는 약간 더 넓으며, 또한 다루고 '\n'있습니다.
derobert

stackoverflow.com/a/30968225/3163618 성능에 큰 차이가있을 수 있습니다.
qwr

답변:


473

파일이 텍스트 모드로 열려 있다고 가정하면 이진을 요구하지 않으면 얻을 수있는 줄 바꿈 문자는 중요하지 않습니다. 컴파일 된 프로그램은 컴파일 된 시스템에 맞는 것을 작성합니다.

유일한 차이점은 std::endl출력 버퍼 를 플러시하고 '\n'그렇지 않다는 것입니다. 버퍼를 자주 플러시하지 않으려면을 사용하십시오 '\n'. 예를 들어 모든 출력을 얻고 프로그램이 불안정한 경우을 사용하십시오 std::endl.


24
또는 버퍼링되지 ::std::cerr않고 ::std::cout각각의 모든 출력 작업으로 플러시되므로 대신 사용 을 고려하십시오 .
Omnifarious

142
@Omnifarious : 오류가 발생하지 않은 std :: cerr이 없습니다. 두 스트림은 함께 동기화되지 않으므로 일부 텍스트를 cout으로 출력하면 버퍼링 될 수 있으며 cerr은 출력으로 직접 이동하여 혼합 모드 표시가됩니다. 예상되는 것 (오류)에 대해 cerr을 사용하고 의도 된 것 (정상 상호 작용)에 대해 cout을 사용하십시오.
Martin York

23
@Lucas : '\ n'이하는 플랫폼을 인식합니다.
CB Bailey

32
@LokiAstari : stderr"오류"에 대한 것이 아닙니다 . 오히려, 대역 외 진단 메시지를위한 것입니다. ./prog > file실제 프로그램 페이로드 만 말하고 저장할 수 있어야 하지만 프로그램은 정상적인 상호 작용에서도 훨씬 더 많은 상태 정보를 출력 할 수 있습니다.
Kerrek SB

13
"많은 구현에서 표준 출력은 라인 버퍼링되며 std :: cout.sync_with_stdio (false)를 실행하지 않으면 '\ n'을 쓰면 플러시가 발생합니다." 여기에서 복사
GuLearn

249

차이점은 다음과 같이 설명 할 수 있습니다.

std::cout << std::endl;

에 해당

std::cout << '\n' << std::flush;

그래서,

  • std::endl출력을 즉시 플러시하려는 경우 사용하십시오 .
  • 사용 \n당신이 (당신이 사용하는 경우 아마도 경우하지 않은 성능에 대해 걱정하는 경우 <<연산자).

나는 \n대부분의 라인에서 사용 합니다.
그런 다음 std::endl단락의 끝에 사용 하십시오 (그러나 그것은 습관이며 일반적으로 필요하지는 않습니다).

다른 주장과 반대로, \n문자 스트림이 파일에가는 (경우에만 라인 시퀀스의 올바른 플랫폼 말에 매핑 std::cinstd::cout) 같은 파일 특별하지만 여전히 파일 (또는 인).


5
대부분의 경우, 이후, 붉은 청어는 "출력이 즉시 볼" cout에 연결되어 cin사용자가 입력을 읽으면에서 의미 cin, cout먼저 플러시됩니다. 그러나에서 읽지 않고 진행률 표시 줄이나 무언가를 표시하려면 cin플러시가 유용합니다.
Chris Jester-Young

9
@LokiAstari : << 연산자를 사용하는 경우 성능에 대해 걱정하지 않아도됩니다 . 왜 그런가요 ? 나는 그것이 operator<<성능이 좋지 않거나 성능에 어떤 대안을 사용할지 몰랐 습니까? 이것을 더 이해하기 위해 몇 가지 자료를 알려주세요.
legends2k

8
@ legends2k : C ++ 스트림이 C printf ()만큼 성능이 좋지 않다는 오래된 아내 이야기가 있습니다. 속도의 주된 차이는 C ++ 스트림을 잘못 사용하는 사람들에 의해 어느 정도 사실입니다. stackoverflow.com/a/1042121/14065 C ++에서 iostream을 C-stream sync_with_stdio(false)과 동기화 해제 하고 출력을 지속적으로 플러시하지 마십시오. 도서관이 언제해야하는지 알아 내십시오. stackoverflow.com/a/1926432/14065
Martin York

6
@Loki : sync_with_stdioiostream을 stdio만큼 빠르게 만드는 도시 전설이 있습니다. 그렇지 않습니다
Ben Voigt

2
@ BenVoigt : 위의 문구에주의를 기울였습니다 (그래서 나는 그들에게 만족합니다). stdio만큼 성능이 좋지 않습니다 (더 많은 일을하기 때문에). 그러나 사람들이 불평하는 많은 성능 격차는 stdio와의 동기화로 인한 것입니다.
Martin York


30

사용하려는 경우 다른 함수 호출이 암시됩니다. std::endl

a) std::cout << "Hello\n";
b) std::cout << "Hello" << std::endl;

a) 연산자를 <<한 번 호출합니다 .
b) 연산자를 <<두 번 호출합니다 .


19
명백 할 수도 있지만 일반적으로 첫 번째 버전은 한 번에 한 줄에 두 번째 버전이 다른 스레드의 쓰기로 분할 될 수있는 단일 행을 작성하는 스레드 프로그램에 큰 영향을 미칩니다. 종종 나는 이것을 피하기 위해 std :: cout << "hello \ n"<< std :: flush라고 쓰고있다.
smparkes 2016 년

무엇에 대해 std::cout << "Hello" << "\n";?
byxor

1
@byxor 다른 답변에서 설명한 버퍼 플러싱을 제외하고 거의 동일합니다. 어쨌든 두 문자열 리터럴을 하나로 병합 할 때 중복됩니다.
iBug

음, 문자열이 인쇄 될 경우는 문자의에 다음 호출되지 <<케이스에 2 것 따라서 나는 하나 또는 두에 대한 필요성 주장하지 않을뿐만 아니라 수 (일반적으로 두 함수 호출을) 차이 와 . <<\nendl
Enrico Maria De Angelis

Lol no, 이것이 \ n을 사용하는 이유는 아닙니다.
Carlo Wood

28

나는 표준에서 이것에 대해 읽은 것을 상기 시켰습니다.

C ++ 프로그램이 CRT와 인터페이스 할 때 C11 표준이 플러싱 정책을 제어해야하므로 표준 스트림의 작동 방식을 정의하는 C11 표준을 참조하십시오.

ISO / IEC 9899 : 201x

7.21.3 §7

프로그램 시작시 세 개의 텍스트 스트림이 사전 정의되어 있으며 표준 입력 (일반 입력 읽기), 표준 출력 (일반 출력 쓰기) 및 표준 오류 (진단 출력 쓰기)와 같이 명시 적으로 열 필요가 없습니다. 처음에 열었을 때 표준 오류 스트림은 완전히 버퍼링되지 않습니다. 표준 입력 및 표준 출력 스트림은 스트림이 대화식 장치를 참조하지 않는 것으로 결정될 수있는 경우에만 완전히 버퍼링됩니다.

7.21.3 §3

스트림이 버퍼링되지 않은 경우 가능한 빨리 소스 또는 대상에서 문자가 표시됩니다. 그렇지 않으면 문자가 블록으로 호스트 환경에 쌓이거나 전송 될 수 있습니다. 스트림이 완전히 버퍼링되면 버퍼가 채워질 때 문자가 호스트 환경과 블록으로 전송되도록 문자가 의도됩니다. 스트림이 라인 버퍼링 될 때, 문자는 개행 문자가 발생할 때 블록으로 호스트 환경에서 또는 호스트 환경으로 전송됩니다. 또한 문자는 버퍼가 채워질 때, 버퍼되지 않은 스트림에서 입력이 요청 될 때 또는 호스트 환경에서 문자를 전송해야하는 라인 버퍼링 된 스트림에서 입력이 요청 될 때 호스트 환경에 블록으로 전송됩니다. .

이 수단 std::coutstd::cin완전히 버퍼링 경우에만 그들은 비 대화 형 장치를 참조한다. 즉, stdout이 터미널에 연결되어 있으면 동작에 차이가 없습니다.

그러나을 std::cout.sync_with_stdio(false)호출 '\n'하면 대화 형 장치로도 플러시되지 않습니다. 그렇지 않으면 '\n'해당되는 std::endl파일에 배관하지 않는 한 : C ++ 심판에 대한 표준 : ENDL .


19

그들은 적절한 줄 끝 문자를 쓸 것입니다. 그 endl 외에도 버퍼가 커밋됩니다. 불필요한 커밋은 성능에 영향을 줄 수 있기 때문에 파일 I / O를 수행 할 때 일반적으로 endl을 사용하고 싶지 않습니다.



10

Qt 및를 사용 endl하면 실수로 잘못된 endl것을 사용하여 매우 놀라운 결과를 얻을 수 있습니다. 다음 코드 스 니펫을 참조하십시오.

#include <iostream>
#include <QtCore/QtCore> 
#include <QtGui/QtGui>

// notice that there is no "using namespace std;"
int main(int argc, char** argv)
{
    QApplication qapp(argc,argv);
    QMainWindow mw;
    mw.show();
    std::cout << "Finished Execution!" << endl;
    // This prints something similar to: "Finished Execution!67006AB4"
    return qapp.exec();
}

내가 (올바른 것 endl대신 std::endl) 썼고 qtextstream.h (QtCore의 일부)에 endl정의 된 함수 가있는 것 같습니다 .

잠재적 인 네임 스페이스 문제 "\n"endl완전히 회피하는 대신에를 사용하면 됩니다 . Qt가 기본적으로하는 것처럼 전역 네임 스페이스에 기호를 넣는 것이 좋지 않은 이유도 좋은 예입니다.


31
어! 누가되고 싶어 using namespace std;? :-)
Steve Folly 2019

2
추잡한. 의견 주셔서 감사합니다, 나는 다른 사람들이 그것에 빠질 것이라고 확신합니다.
Geek

@SteveFolly 내가 할. 왜 안돼?
ʇolɐǝz ǝɥʇ qoq

@ ʇolɐǝzǝɥʇqoq 헤더 파일에서 그렇게하지 않는 한 괜찮습니다.
smerlin

1
@ ʇolɐǝzǝɥʇqoq 피하십시오 using namespace std;. 나쁜 습관으로 간주됩니다. “네임 스페이스 std를 사용하는 이유”를
LF


2

std::endl조작은 동일합니다 '\n'. 그러나 std::endl항상 스트림을 플러시합니다.

std::cout << "Test line" << std::endl; // with flush
std::cout << "Test line\n"; // no flush

1

자신의 랩톱 이외의 다른 프로그램에서 프로그램을 실행하려는 경우에는 endl절대로이 명령문을 사용하지 마십시오 . 특히 짧은 줄을 많이 쓰거나 파일에 단일 문자를 자주 본 경우. 사용 endl된다 NFS와 같은 네트워크 파일 시스템을 죽일 것을 알고있다.


플러싱 때문입니까? 어떻게 가능한지 알 수 있습니다.
Geek

@ 헤드 참으로. 또한 디스크 IO 성능이 저하되는 것을 보았습니다.
sbi

0

함께 참조 이것은 인 출력 전용 I / O 매니퓰레이터 .

std::endl삽입물 출력 시퀀스 OS로 개행 문자 것처럼 호출하여 플러시 os.put(os.widen('\n'))하였다 os.flush().

사용시기 :

이 조작기는 즉시 출력 라인을 생성하는 데 사용될 수 있습니다 .

예 :

장기 실행 프로세스의 출력을 표시 할 때 여러 스레드의 활동을 기록하거나 예기치 않게 충돌 할 수있는 프로그램의 활동을 기록합니다.

또한

생성 된 프로세스가 화면 I / O를 수행하는 경우 std :: system을 호출하기 전에 std :: cout의 명시 적 플러시도 필요합니다. 대부분의 다른 일반적인 대화식 I / O 시나리오에서 std :: cout과 함께 사용하면 std :: endl은 중복됩니다. std :: cin, std :: cerr 로의 출력 또는 프로그램 종료는 std :: cout을 호출하기 때문입니다. .플러시(). 일부 소스에서 권장하는 '\ n'대신 std :: endl을 사용하면 출력 성능이 크게 저하 될 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.