Pergunta

Como são \r e \n diferente? Eu acho que tem algo a ver com Unix versus Windows vs Mac, mas eu não sei exatamente como eles são diferentes, e que para procurar / partida em expressões regulares.

Foi útil?

Solução

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

No "velho" impressoras, \r enviou a cabeça para trás impressão para o início da linha, e \n avançado o papel por uma linha. Ambos eram, portanto, necessário para começar a imprimir na próxima linha.

Obviamente que é um pouco irrelevante agora, embora dependendo do console, você ainda pode ser capaz de usar \r para mover para o início da linha e substituir o texto existente.

Mais importante, Unix tende a usar \n como um separador de linha; O Windows tende a usar \r\n como um separador de linha e Macs (até OS 9) usado usar \r como separador de linha. (Mac OS X é Unix-y, então usos \n vez;. Pode haver algumas situações de compatibilidade onde \r é usado em vez embora)

Para obter mais informações, consulte a Wikipedia artigo nova linha .

EDIT: Esta é sensível à linguagem. Em C # e Java, por exemplo, \n Sempre meios Unicode U + 000A, que é definido como alimentação de linha. Em C e C ++ a água é um pouco mais enlameado, como o sentido é específico da plataforma. Veja os comentários para mais detalhes.

Outras dicas

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

Pense em um teletipo de idade. A cabeça de impressão está posicionada em alguma linha e, em alguns coluna. Quando você envia um carácter de impressão para o teletipo, ele imprime o caractere na posição atual e move a cabeça para a próxima coluna. (Este é conceitualmente o mesmo que uma máquina de escrever, exceto que as máquinas de escrever tipicamente mudou o papel com relação à cabeça de impressão.)

Quando você queria terminar a linha actual e iniciar na próxima linha, que tinha que fazer duas etapas separadas:

  1. mover a parte de trás da cabeça de impressão para o início da linha, então
  2. movê-lo para baixo para a próxima linha.

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

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

Nos dias de teletypes e impressoras tecnologia início, as pessoas realmente se aproveitou do fato de que estes eram duas operações distintas. Ao enviar um CR, sem que se lhe segue por um LF, pode imprimir sobre a linha que você já impresso. Isto permitiu efeitos como acentos, negrito e sublinhado. Alguns sistemas sobreposta várias vezes para evitar senhas de ser visível na cópia impressa. Em terminais CRT série início, CR foi uma das maneiras de controlar a posição do cursor, a fim de texto update estiver na tela.

Mas a maior parte do tempo, você realmente só queria ir para a próxima linha. Em vez de requerer que o par de caracteres de controlo, alguns sistemas permitidos apenas um ou o outro. Por exemplo:

  • variantes Unix (incluindo versões modernas de Mac) usar apenas um personagem LF para indicar uma nova linha.
  • Old (pré-OSX) Macintosh arquivos usados ??apenas um carácter CR para indicar uma nova linha.
  • VMS, CP / M, DOS, Windows, e muitos protocolos de rede ainda esperam que ambos:. CR LF
  • sistemas antigos da IBM que costumavam EBCDIC padronizado em NL - um personagem que não existe mesmo no caráter ASCII conjunto. Em Unicode, NL é U+0085 NEXT LINE, mas o valor real é EBCDIC 0x15.

Por que diferentes sistemas de escolher métodos diferentes? Simplesmente porque não havia nenhum padrão universal. Onde seu teclado provavelmente diz "Enter", teclados antigos costumavam dizer "Return", que era curto para retorno de carro. Na verdade, em um terminal serial, pressionando Return realmente envia o personagem CR. Se você estivesse escrevendo um editor de texto, seria tentador usar apenas esse personagem como ele veio da terminal. Talvez seja por isso que os Macs mais antigos usados ??apenas CR.

Agora que temos normas , há mais maneiras de representar as quebras de linha. Embora extremamente raro na natureza, Unicode tem novos personagens como:

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

Mesmo antes Unicode veio junto, programadores queria maneiras simples para representar alguns dos códigos de controle mais úteis sem se preocupar com o conjunto de caracteres subjacente. C tem várias sequências de escape para a representação de códigos de controlo:

  • \a (para alerta), que toca o sino teletipo ou faz com que o sinal sonoro do terminal
  • \f (para alimentação de formulário), que se move para o início da próxima página
  • \t (por guia) que move a cabeça de impressão para a próxima posição de tabulação horizontal

(Esta lista é intencionalmente incompletas.)

Esse mapeamento acontece em tempo de compilação -. O compilador vê \a e coloca o valor que a magia é usada para tocar a campainha

tha Noticet maioria destes mnemônicos têm correlações diretas para códigos de controle ASCII. Por exemplo, \a iria mapear para 0x07 BEL. Um compilador poderia ser escrito para um sistema que algo usado 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íficas poderiam ser mapeados para códigos de controle em outros conjuntos de caracteres.

Huzzah! Portabilidade!

Bem, quase. Em C, eu poderia escrever printf("\aHello, World!"); que toca o sino (ou sinais) e emite uma mensagem. Mas se eu queria então imprimir algo na linha seguinte, eu ainda preciso saber o que a plataforma de acolhimento exige para passar para a próxima linha de saída. CR LF? CR? LF? NL? Algo mais? Tanto para a portabilidade.

C possui dois modos para I / O: binário e de texto. No modo de binário, o que quer que os dados são enviados é transmitido como está. Mas em modo texto, há um tempo de execução tradução que converte um caractere especial para o que quer que as necessidades plataforma host para uma nova linha (e vice-versa).

Great, então qual é o caráter especial?

Bem, isso é implementação dependentes, 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 em qual (modo texto tempo de compilação para um valor de caractere definido pela implementação em ) é então mapeado de novo a tempo de execução para o carácter real (ou sequência de caracteres) requerido pela plataforma subjacente para mover para a próxima linha.

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

Esta viagens até muitos C e programadores C ++. Se você fosse para pesquisar 100 deles, pelo menos 99 vão te dizer que alimentação de linha meios \n. Isso não é inteiramente verdade. A maioria (talvez todos) C e C ++ implementações usar LF como o valor intermediário mágica para \n, mas isso é um detalhe de implementação. É possível que um compilador para usar um valor diferente. Na verdade, se o conjunto de caracteres de acolhimento não é um super conjunto de ASCII (por exemplo, se é EBCDIC), então \n quase certamente não ser LF.

Assim, em C e C ++:

  • \r é, literalmente, um retorno de carro.
  • \n é um valor mágico que é traduzido (em modo texto) em em tempo de execução de / para a semântica de nova linha da plataforma host.
  • \r\n é quase sempre um erro portabilidade. No modo de texto, este é traduzido para CR seguido por sequência de nova linha da plataforma - provavelmente não o que está destinado. Em modo binário, isto é traduzido para CR seguido por algum valor mágico que pode não ser LF -. Possivelmente, não o que está destinado
  • \x0A é a maneira mais portátil para indicar um LF ASCII, mas você só quer fazer isso em modo binário. A maioria das implementações em modo texto irá tratar isso como \n.
  • "\ r" => Voltar
  • "\ n" => nova linha ou Linefeed (Semântica)

  • sistemas baseados em Unix usam apenas um "\ n" para acabar com uma linha de texto.

  • DOS usa "\ r \ n" para acabar com uma linha de texto.
  • Algumas outras máquinas utilizadas apenas um "\ r". (Commodore, Apple II, Mac OS antes do OS X, etc ..)

Em suma \ r tem o valor ASCII 13 (CR) e \ n tem o valor ASCII 10 (LF). Mac usa CR como a linha delimitador (pelo menos, ele tinha antes, eu não tenho certeza para Macs modernos), * nix usa LF e Windows usa tanto (CRLF).

\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 este resultado:

hai

\n é para a nova linha.

Além de resposta de @ Jon Skeet:

Tradicionalmente o Windows tem usado \ r \ n, Unix \ n e Mac \ r, porém mais recentes usam Macs \ n como eles são baseados em UNIX.

em C # eu achei que eles usam \ r \ n em uma string.

\ r é Carriage Return; \ N é New Line (Line Feed) ... depende do sistema operacional como o que cada meio. Leia este artigo para saber mais sobre a diferença entre '\ n' e '\ r \ n' ... no C.

\ r usado para retorno de carro. (Valor ASCII é 13) \ N utilizado para a nova linha. (ASCII valor é 10)

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