Qual é a diferença entre \ r e \ n?

245

Como são \re \ndiferentes? Eu acho que tem algo a ver com Unix x Windows x Mac, mas não sei exatamente como eles são diferentes e quais procurar / corresponder em expressões regulares.

Sam Lee
fonte
1
Isso precisa de uma tag de idioma. Línguas diferentes têm diferentes interpretações de '\n'.
Adrian McCarthy

Respostas:

383

Eles são personagens diferentes. \ré retorno de carro e\n é avanço de linha.

Nas impressoras "antigas", \renvie a cabeça de impressão de volta ao início da linha e\n avançava o papel em uma linha. Ambos eram, portanto, necessários para começar a imprimir na próxima linha.

Obviamente isso é um tanto irrelevante agora, embora, dependendo do console, você ainda possa usar \r para ir para o início da linha e substituir o texto existente.

Mais importante, o Unix tende a usar \ncomo um separador de linhas; O Windows costuma usar \r\ncomo separador de linhas e os Macs (até OS 9) costumam usar \rcomo separador de linhas. (O Mac OS X é o Unix-y, portanto, usa-o \n; pode haver algumas situações de compatibilidade em que\r é usado.)

Para mais informações, consulte o artigo de nova linha da Wikipedia .

EDIT: Isso é sensível ao idioma. Em C # e Java, por exemplo, \n sempre significa Unicode U + 000A, que é definido como avanço de linha. Em C e C ++, a água é um pouco mais turva, pois o significado é específico da plataforma. Veja os comentários para obter detalhes.

Jon Skeet
fonte
22
+1 para idosos. Saída do terminal usada para controlar diretamente um terminal eletrônico glorificado (o seu TTY antes da exibição do sofisticado CRT). Portanto, obtemos artefatos maravilhosos daqueles no retorno de carro e nos caracteres de nova linha (os quais podem ser necessários, como Jon Skeet mencionou) e coisas como \ a "bell", \ b "backspace" (não confundir com "delete ") e todos os outros caracteres de controle necessários para se comunicar com um tty.
erjiang
35
Mais um +1 para idosos. Você ainda pode pressionar Ctrl + G em um prompt de comando do Windows, pressionar enter e o alto-falante do PC emitirá um bipe. Isso sobra desde os tempos antigos.
Dave Carlile
@ Cara de codificação ruim, realmente? No Vista, apenas diz que "'' não é reconhecido como um comando interno ou externo" "
Ponkadoodle
2
@AdrianMcCarthy: É claro que a pergunta não especifica C ou C ++ aqui. Em C #, por exemplo, \n é garantido que seja nova linha (seção 2.4.4.4). Claro, seria bom se o OP tivesse especificado a plataforma ... Além disso, acho que esse nível de detalhe seria mais confuso do que útil para alguém que está apenas perguntando a diferença.
Jon Skeet
2
@AdrianMcCarthy: Mas em C # e Java, pelo menos, é um feed de linha. É U + 000A, que é nomeado por Unicode como "LINE FEED" (e NEW LINE). Vou editar para mencionar o caso especial de C e C ++, mas acredito realmente que são casos especiais, e não o contrário.
precisa
91

Em C e C ++, \né um conceito, \ré um personagem e \r\né (quase sempre) um bug de portabilidade.

Pense em um teletipo antigo. A cabeça de impressão está posicionada em alguma linha e em alguma coluna. Quando você envia um caractere imprimível ao teletipo, ele o imprime na posição atual e move a cabeça para a próxima coluna. (Conceitualmente, é o mesmo que uma máquina de escrever, exceto que as máquinas de escrever geralmente movem o papel em relação à cabeça de impressão.)

Quando você queria terminar a linha atual e começar na próxima linha, precisava executar duas etapas separadas:

  1. mova a cabeça de impressão de volta para o início da linha e, em seguida,
  2. mova-o para a próxima linha.

O ASCII codifica essas ações como dois caracteres de controle distintos:

  • \x0D(CR) move a cabeça de impressão de volta ao início da linha. (Unicode codifica isso como U+000D CARRIAGE RETURN.)
  • \x0A(LF) move a cabeça de impressão para a próxima linha. (Unicode codifica isso como U+000A LINE FEED.)

Na época dos teletipos e das primeiras impressoras de tecnologia, as pessoas realmente aproveitavam o fato de que eram duas operações separadas. Ao enviar um CR sem segui-lo por um LF, você pode imprimir sobre a linha já impressa. Isso permitiu efeitos como acentos, negrito e sublinhado. Alguns sistemas foram impressos várias vezes para impedir que as senhas fossem visíveis em cópia impressa. Nos primeiros terminais seriais de CRT, o CR era uma das maneiras de controlar a posição do cursor para atualizar o texto já na tela.

Mas na maioria das vezes, você realmente só queria ir para a próxima linha. Em vez de exigir o par de caracteres de controle, alguns sistemas permitiam apenas um ou outro. Por exemplo:

  • As variantes do Unix (incluindo versões modernas do Mac) usam apenas um caractere LF para indicar uma nova linha.
  • Os arquivos antigos do Macintosh (pré-OSX) usavam apenas um caractere CR para indicar uma nova linha.
  • VMS, CP / M, DOS, Windows e muitos protocolos de rede ainda esperam os dois: CR LF.
  • Sistemas antigos da IBM que usavam EBCDIC padronizado em NL - um caractere que nem existe no conjunto de caracteres ASCII. Em Unicode, NL é U+0085 NEXT LINE, mas o valor EBCDIC real é 0x15.

Por que sistemas diferentes escolheram métodos diferentes? Simplesmente porque não havia um padrão universal. Onde seu teclado provavelmente diz "Enter", os teclados antigos costumavam dizer "Return", que era a abreviação de Carriage Return. De fato, em um terminal serial, pressionar Retornar envia o caractere CR. Se você estivesse escrevendo um editor de texto, seria tentador usar esse caractere quando ele chegasse do terminal. Talvez seja por isso que os Macs mais antigos usassem apenas CR.

Agora que temos padrões , há mais maneiras de representar quebras de linha. Embora extremamente raro na natureza, o Unicode possui novos caracteres como:

  • U+2028 LINE SEPARATOR
  • U+2029 PARAGRAPH SEPARATOR

Mesmo antes do surgimento do Unicode, os programadores queriam maneiras simples de representar alguns dos códigos de controle mais úteis sem se preocupar com o conjunto de caracteres subjacente. C possui várias seqüências de escape para representar códigos de controle:

  • \a (alerta) que toca a campainha do teletipo ou emite um sinal sonoro ao terminal
  • \f (para feed de formulário) que passa para o início da próxima página
  • \t (para guia) que move a cabeça de impressão para a próxima posição de guia horizontal

(Esta lista está intencionalmente incompleta.)

Esse mapeamento acontece no momento da compilação - o compilador vê \ae coloca qualquer valor mágico usado para tocar a campainha.

Observe que a maioria desses mnemônicos tem correlações diretas com os códigos de controle ASCII. Por exemplo, \amapearia para0x07 BEL . Um compilador pode ser escrito para um sistema que usa algo diferente de ASCII para o conjunto de caracteres do host (por exemplo, EBCDIC). A maioria dos códigos de controle que tinham mnemônicos específicos pode ser mapeada para controlar códigos em outros conjuntos de caracteres.

Huzzah! Portabilidade!

Bem, quase. Em C, eu poderia escrever o printf("\aHello, World!");que toca a campainha (ou emite um sinal sonoro) e envia uma mensagem. Mas se eu quisesse imprimir algo na próxima linha, ainda precisaria saber o que a plataforma host requer para passar para a próxima linha de saída. CR LF? CR? LF? NL? Algo mais? Tanta coisa para portabilidade.

C possui dois modos de E / S: binário e texto. No modo binário, quaisquer dados enviados são transmitidos como estão. Mas no modo de texto, há uma tradução em tempo de execução que converte um caractere especial para o que a plataforma host precisa para uma nova linha (e vice-versa).

Ótimo, então qual é o personagem especial?

Bem, isso é dependente de implementação, também, mas há uma maneira independente de implementação para especificar que: \n. É normalmente chamado de "caractere de nova linha".

Este é um ponto sutil, mas importante: \n é mapeado no tempo de compilação para um valor de caractere definido pela implementação que (no modo de texto) é mapeado novamente no tempo de execução para o caractere real (ou sequência de caracteres) exigido pela plataforma subjacente para mover para a próxima linha.

\né diferente de todos os outros literais de barra invertida porque há dois mapeamentos envolvidos. Esse mapeamento em duas etapas torna \nsignificativamente diferente do que o uniforme \r, que é simplesmente um mapeamento em tempo de compilação para CR (ou o código de controle mais semelhante em qualquer que seja o conjunto de caracteres subjacente).

Isso aciona muitos programadores de C e C ++. Se você quiser pesquisar 100 deles, pelo menos 99 dirão que isso \nsignifica feed de linha. Isso não é inteiramente verdade. A maioria das implementações (talvez todas) de C e C ++ usa LF como o valor intermediário mágico \n, mas esse é um detalhe da implementação. É possível para um compilador usar um valor diferente. De fato, se o conjunto de caracteres host não for um superconjunto de ASCII (por exemplo, se for EBCDIC), então\n quase certamente não será LF.

Então, em C e C ++:

  • \r é literalmente um retorno de carro.
  • \né um valor mágico que é traduzido (no modo de texto) em tempo de execução de / para a semântica de nova linha da plataforma host.
  • \r\nquase sempre é um bug de portabilidade. No modo de texto, isso é traduzido para CR seguido pela sequência de nova linha da plataforma - provavelmente não é o que se pretende. No modo binário, isso é traduzido para CR seguido por algum valor mágico que pode não ser LF - possivelmente não é o que se pretende.
  • \x0Aé a maneira mais portátil de indicar um ASCII LF, mas você só deseja fazer isso no modo binário. A maioria das implementações em modo de texto tratará dessa maneira \n.
Adrian McCarthy
fonte
Me deparei com este post enquanto tentava descobrir como dividir a entrada <textarea> no Python, e \r\né realmente a única maneira de dividir corretamente as linhas em elementos de lista separados. Isso me faz pensar se isso é algum artefato HTML estranho ou se tem a ver com a maneira como o Python ingere a string do meu requestobjeto.
Pat Jones
11
  • "\ r" => Voltar
  • "\ n" => Nova linha ou avanço de linha (semântica)

  • Os sistemas baseados em Unix usam apenas "\ n" para finalizar uma linha de texto.

  • O Dos usa "\ r \ n" para terminar uma linha de texto.
  • Algumas outras máquinas usavam apenas "\ r". (Commodore, Apple II, Mac OS anterior ao OS X, etc.)
NoMoreZealots
fonte
5

\r é usado para apontar para o início de uma linha e pode substituir o texto a partir daí, por exemplo

main()
{
printf("\nab");
printf("\bsi");
printf("\rha");
}

Produz esta saída:

hai

\n é para nova linha.

DAYA PHILIP
fonte
4

Em suma, \ r possui o valor ASCII 13 (CR) e \ n tem o valor ASCII 10 (LF). O Mac usa o CR como delimitador de linha (pelo menos, antes, não tenho certeza dos macs modernos), * o nix usa o LF e o Windows usa os dois (CRLF).

Josip Medved
fonte
1
Os sistemas Mac OS X usam LF por padrão (já que é baseado no BSD Unix).
dreamlax
3

Além da resposta de @Jon Skeet:

Tradicionalmente, o Windows usa \ r \ n, Unix \ n e Mac \ r, no entanto, os Macs mais novos usam \ n por serem baseados em unix.

Greg
fonte
2

em C #, descobri que eles usam \ r \ n em uma string.

Wesley
fonte
2

\ R é retorno de carro; \ n é Nova linha (avanço de linha) ... depende do sistema operacional quanto ao que cada um significa. Leia este artigo para saber mais sobre a diferença entre '\ n' e '\ r \ n' ... em C.

Nathan Loding
fonte
1

usado para retorno de carro. (O valor ASCII é 13) \ n usado para a nova linha. (O valor ASCII é 10)

Manjeet Kumar
fonte