Pergunta

Muitos C ++ livros contêm exemplo de código como este ...

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

... então eu sempre fiz isso também. Mas eu já vi um monte de código de desenvolvedores trabalhando como este em vez disso:

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

Existe uma razão técnica preferir um sobre o outro, ou é apenas uma questão de estilo de codificação?

Foi útil?

Solução

Os caracteres de delimitação de linhas diferentes, não importa, assumindo que o arquivo é aberto no modo de texto, que é o que obtém a menos que você pedir binário. O programa compilado irá escrever a coisa correta para o sistema compilado.

A única diferença é que std::endl rubores o tampão de saída, e '\n' não. Se você não quer que o tampão corado com freqüência, uso '\n'. Se você fizer (por exemplo, se você deseja obter toda a saída, eo programa é instável), o uso std::endl.

Outras dicas

A diferença pode ser ilustrada pela seguinte:

std::cout << std::endl;

é equivalente a

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

Assim,

  • Use std::endl Se você quiser forçar uma lave imediatamente para a saída.
  • Use \n se você está preocupado com o desempenho (que provavelmente não é o caso se você estiver usando o operador <<).

Eu uso \n na maioria das linhas.
Em seguida, use std::endl no final de um parágrafo (mas isso é apenas um hábito e não costumam ser necessário).

Ao contrário de outras reivindicações, o personagem \n é mapeado para o fim plataforma correta da seqüência de linha somente se o fluxo está indo para um arquivo (arquivos std::cin e std::cout ser especial, mas ainda (ou arquivo-like)).

Pode haver problemas de desempenho, forças std::endl uma onda de fluxo de saída.

Lembrei-me de ler sobre isso no padrão, então aqui vai:

Veja C11 padrão que define como os fluxos padrão se comportam, como programas em C ++ de interface do CRT, o padrão C11 devem reger a política rubor aqui.

ISO / IEC 9899: 201x

7.21.3 §7

No início do programa, três fluxos de texto são predefinidos e não precisa ser aberto explicitamente - entrada padrão (para leitura de entrada convencional), a saída padrão (para a escrita saída convencional), e erro padrão (para escrever saída de diagnóstico). como inicialmente aberta, o fluxo de erro padrão não é totalmente tamponada; a entrada padrão e padrão fluxos de saída estão completamente armazenados se e não só, se a corrente pode ser determinada para se referir para um dispositivo interactivo.

7.21.3 §3

Quando um fluxo é sem buffer, os personagens são destinados a aparecer a partir da fonte ou no destino o mais rápido possível. Caso contrário, os caracteres podem ser acumulados e transmitidos para ou a partir do meio de acolhimento como um bloco. Quando uma corrente está totalmente tamponada, caracteres se destinam a ser transmitidos para ou a partir do meio de acolhimento como um bloco quando um tampão está cheia. Quando uma corrente é tamponada linha, os caracteres se destinam a ser transmitidos para ou a partir do ambiente de host como um bloco quando um caractere de nova linha é encontrado. Além disso, os caracteres se destinam a ser transmitidos como um bloco para o hospedeiro ambiente quando um tampão está cheia, quando a entrada for solicitada a corrente não tamponada, ou quando a entrada é solicitada em uma linha de fluxo tamponada que requer a transmissão de personagens do ambiente de host. O apoio a estas características é , E pode ser afectada por meio das funções setbuf e setvbuf definido pela implementação.

Isto significa que std::cout e std::cin estão totalmente em buffer se e só se eles estão se referindo a um dispositivo não-interativo. Em outras palavras, se stdout está ligado a um terminal, em seguida, não há nenhuma diferença no comportamento.

No entanto, se std::cout.sync_with_stdio(false) é chamado, então '\n' não irá causar um flush até mesmo para dispositivos interativos. Caso contrário '\n' é equivalente a std::endl menos tubulação de arquivos:. c ++ ref em std :: endl

Há uma outra chamada de função implícita lá se você estiver indo para usar std::endl

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

a) chama operador << uma vez.
b) chama << operador duas vezes.

Eles serão ambas escreve o caractere apropriado de fim de linha (s). Além de que endl fará com que o tampão deve ser comprometida. Você normalmente não quiser usar endl ao fazer arquivo de I / O, porque os commits desnecessários pode afetar o desempenho.

Não é grande coisa, mas endl não vai funcionar em boost :: lambda .

(cout<<_1<<endl)(3); //error

(cout<<_1<<"\n")(3); //OK , prints 3

Se você usar o Qt e endl, você pode acidentalmente usar o endl errado, aconteceu comigo hoje e eu era como ..WTF ??

#include <iostream>
#include <QtCore/QtCore> 
#include <QtGui/QtGui>
//notice that i dont have a "using namespace std;"
int main(int argc, char** argv)
{
    QApplication qapp(argc,argv);
    QMainWindow mw;
    mw.show();
    std::cout << "Finished Execution !" << endl << "...";
    // Line above printed: "Finished Execution !67006AB4..."
    return qapp.exec();
}

É claro que foi o meu erro, desde que eu deveria ter escrito std::endl, , mas se você usar endl, qt e using namespace std; depende da ordem dos arquivos incluem se o endl correto será usado. *

Claro que você pode recompilar Qt para usar um namespace, de modo a obter um erro de compilação para o exemplo acima.

EDIT: Esqueci de mencionar, endl do Qt é declarada em "qtextstream.h" que faz parte do QtCore

* EDIT2:. C ++ irá escolher o endl correta se você tiver um using para std::cout ou o std namespace, uma vez std::endl é no mesmo namespace como std::cout, mecanismo ADL C ++ 's vai pegar std::endl

Eu sempre tive o hábito de apenas usando std :: endl, porque é fácil para mim ver.

Com referência Este é um output-only I / O manipulador .

std::endl Insere um caractere de nova linha para o OS sequência de saída e libera-lo como se chamando os.put(os.widen('\n')) seguido por os.flush().

Quando usar:

Este manipulador pode ser usado para produzir uma linha de saída imediatamente ,

por exemplo.

ao exibir a saída de um processo de longa duração, registrando a atividade de vários segmentos ou entrar actividade de um programa que pode falhar de forma inesperada.

Também

Um esvaziamento explícito de std :: cout também é necessária antes de uma chamada para std :: sistema, se executa o processo gerado qualquer tela I / O. Na maioria dos outros cenários habituais I / O interativos, std :: endl é redundante quando usado com std :: cout porque qualquer entrada de std :: cin, saída para std :: cerr, ou forças de terminação programa uma chamada para std :: cout .rubor(). Uso de std :: endl no lugar de '\ n', encorajados por algumas fontes, pode desempenho de saída significativamente degrade.

Se você pretende executar o programa em qualquer outra coisa do que o seu próprio computador portátil, nunca use a instrução endl. Especialmente se você estiver escrevendo um monte de linhas curtas ou como muitas vezes tenho visto caracteres simples para um arquivo. O uso de endl é saber para matar os sistemas de arquivos em rede como NFS.

O manipulador endl é equivalente a '\'. Mas endl sempre libera o fluxo.

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

Se você não percebeu, endl é como pressionar a tecla Enter enquanto "\n" é como pressionar ENTER CHAVE + barra de espaço.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top