Différence entre '\ n' et '\ r \ n'

99

Oui, je suis conscient que '\n'écrit une nouvelle ligne sous UNIX alors que pour Windows , il y a la séquence de deux caractères: '\r\n'. Tout cela est très bien en théorie, mais ma question est pourquoi ? Pourquoi le caractère de retour chariot est-il extra dans Windows? Si UNIX peut le faire dans \npourquoi cela prend-il deux caractères à Windows pour le faire?

Je lis le livre de David Beazley dans Python et il dit:

Par exemple, sous Windows, l'écriture du caractère '\ n' génère en réalité la séquence de deux caractères '\ r \ n' (et lors de la lecture du fichier, '\ r \ n' est traduit en un seul '\ n' personnage).

Pourquoi cet effort supplémentaire?

Je vais être honnête. Je connais la différence depuis longtemps, mais je n'ai jamais pris la peine de demander POURQUOI. J'espère qu'on y répond aujourd'hui.

Merci pour votre temps.

sukhbir
la source
5
Il convient également de noter que Windows n'est pas le seul à utiliser \r\n. Il est également utilisé par la plupart des protocoles Internet textuels (tels que SMTP, HTTP, etc.) pour la même raison que Windows (historique).
Dean Harding
3
De même, lorsque vous utilisez Java et que vous utilisez des chaînes de format (par exemple System.out.printf()ou String.format()), assurez-vous de les utiliser %ncomme CRLF à des fins de compatibilité avec les systèmes d’exploitation. \nest obsolète.
Gary Rowe
J'ai vu \n\rplusieurs fois. (Je pense que c'était quelque chose de NetWare.)
grawity
1
Il existe très peu de programmes Windows nécessitant CRLF. CRLF est peut-être la valeur par défaut, mais presque tout détecte automatiquement et utilise parfaitement la FL. Tous mes éditeurs de texte sous Windows sont configurés pour utiliser les LF pour tous les nouveaux fichiers, et ce n'est vraiment pas un problème.
Kevin

Réponses:

124

Rétrocompatibilité.

Windows est rétro-compatible avec MS-DOS (même agressivement) et MS-DOS a utilisé la convention CR-LF car MS-DOS était compatible avec CP / M-80 (un peu par hasard) qui utilisait la convention CR-LF car comment vous conduisiez une imprimante (car les imprimantes étaient à l’origine des machines à écrire contrôlées par ordinateur).

Les imprimantes disposent d’une commande distincte pour déplacer le papier d’une ligne à l’autre, et d’une commande distincte pour ramener le chariot (où le papier a été monté) dans la marge de gauche.

C'est pourquoi. Et, oui, c'est une gêne, mais cela fait partie du contrat qui a permis à MS-DOS de gagner sur CP / M, et Windows 95 de gagner sur toutes les autres interfaces graphiques en plus de DOS, et Windows XP de prendre le relais. à partir de Windows 98.

(Remarque: les imprimantes laser modernes disposent toujours de ces commandes, car elles sont également compatibles avec les précédentes imprimantes - HP le fait bien.)

Pour ceux qui ne connaissent pas les machines à écrire, voici une vidéo montrant comment la frappe a été effectuée: http://www.youtube.com/watch?v=LJvGiU_UyEQ . Notez que le papier est d'abord soulevé, puis que le chariot est renvoyé, même si cela se produit par un simple mouvement. Le ding a informé la dactylographe que la fin était proche, et de s'y préparer.


la source
3
Comment Unix, avec son \ n, ne travaillait-il qu'avec les anciennes imprimantes? Je suppose qu'ils avaient des consoles Unix connectées à des imprimantes de type machine à écrire?
Senthil Kumaran
3
@Senthil, sous Unix, le caractère de fin de ligne est converti par le pilote final. C'est juste une décision de conception différente.
2
@Senthil, pour être précis, sous Unix, les imprimantes et les terminaux sont résumés dans le système d'exploitation et leur description détermine les séquences d'octets générées pour le périphérique. CP / M n'avait aucune telle abstraction, laissant tout le programme en cours d'exécution - ceci est probablement dû au fait que cela n'était pas nécessaire pour tous les programmes. Par conséquent, le placer dans le système d'exploitation résident enlèverait une mémoire précieuse aux programmes n'en ayant pas besoin. Rappelez-vous que CP / M a été conçu pour un système de 16 kilo-octets .
1
"Ainsi, une caractéristique majeure de la conception de ce qui est sans doute le système de transport le plus avancé au monde a été à l'origine déterminée par la largeur du derrière d'un cheval." Et il en va de même pour les logiciels. astrodigital.org/space/stshorse.html
Ryan Michela
1
@Ryan, légende urbaine. Démystifié sur snopes.com/history/american/gauge.htm
20

Autant que je sache, cela remonte à l'époque des machines à écrire.

\r Est le retour chariot, qui est ce qui se déplace où vous tapez sur la page vers la gauche (ou à droite si c'est votre culture)

\n est une nouvelle ligne qui déplace votre papier d’une ligne vers le haut.

Ne faire qu'une seule de ces opérations sur une machine à écrire vous placerait au mauvais endroit pour commencer à écrire une nouvelle ligne de texte.

Lorsque les ordinateurs sont arrivés, certaines personnes ont conservé l'ancien modèle, mais d'autres se sont rendu compte que ce n'était pas nécessaire et ont encapsulé une nouvelle ligne complète en un seul caractère.

Matt Ellen
la source
7
Alors, pourquoi Windows s'en tient-il encore ?
Sukhbir
8
Rétrocompatibilité. Imaginez combien de documents texte casseraient s'ils changeaient maintenant
Matt Ellen
4
Strictement parlant, "oddball" est l'unixoïde "utiliser uniquement la nouvelle ligne", initialement fait (je crois) pour réduire le nombre de caractères stockés (la traduction en CR LF est effectuée dans le pilote du terminal, c'est l'indicateur "onlcr" qui le contrôle pour la sortie
Vatine
3
Windows avait un prédécesseur nommé DOS, qui avait la même fin de ligne. Windows a gardé la compatibilité. DOS avait ses prédécesseurs, à savoir CP / M. Cela utilisait aussi CRLF. DOS gardé la compatibilité. Le développement de CP / M a été influencé par les TOPS des DEC. Et vous pouvez deviner quel alignement ils ont utilisé. :-) La compatibilité explique beaucoup.
Mnementh
5
OK, mais pourquoi le Bloc-notes ne reconnaît-il toujours pas les fins de ligne "\ n"?
dan04
8

Je ne sais pas si cela est de notoriété publique, mais il convient de noter que CR est toujours compris par les émulateurs de terminaux modernes:

$ printf "hey world\rsup\n"
sup world

C'est pratique pour les indicateurs de progrès, par exemple

for i in {1..100}
do
    printf "\rLoading... %d%%" $i
    sleep 0.01
done
echo
Daniel Lubarov
la source
1
Sur les anciennes imprimantes linéaires IBM (par exemple, la 1403), la convention était de traiter le premier caractère de la mémoire tampon de lignes comme un caractère de contrôle de chariot. Blank signifiait avancer d'une ligne et imprimer. Plus signifiait omettre l’espacement et était utilisé, par exemple, pour souligner. Un zéro signifiait double-espace et un moins à triple-espace. Un «1» est placé en haut de la page suivante et les autres chiffres sont avancés jusqu'à des positions verticales définies par l'utilisateur (utilisés pour remplir des formulaires préimprimés).
George
7

Auparavant, le saut de ligne signifiait que la platine - le rouleau sur lequel vous tapez - faisait pivoter une ligne, ce qui faisait apparaître du texte sur la ligne suivante ... mais dans la colonne suivante.

Retour de chariot signifiait "renvoyer le bit avec lequel vous tapez au début de la ligne".

Windows utilise CR + LF parce que MS-DOS l'a fait, parce que CP / M l'a fait, parce que cela avait du sens pour les lignes série.

Unix a copié sa convention \ n comme le faisait Multics.

Je suppose que si vous creusez suffisamment, vous constaterez un désaccord politique entre les développeurs.

(Vous avez laissé de côté le bit amusant supplémentaire, où la convention Mac est (ou était) d'utiliser simplement CR pour séparer les lignes. Et maintenant, Unicode a également son propre séparateur de ligne, U + 2028!)

Frank Shearar
la source
Hou la la! Je ne savais pas que le Mac ...
Michael K
Je ne suis pas sûr que vous trouveriez un désaccord politique. Il est également possible que vous trouviez des personnes faisant des choses similaires de manière indépendante.
David Thornley
1
Quand différents organismes de normalisation sont-ils impliqués? Je serais surpris de ne pas trouver de raisons politiques!
Frank Shearar
6

Histoire du personnage Newline (Wikipedia):

ASCII a été développé simultanément par l'ISO et l'ASA, l'organisation qui a précédé l'ANSI. Au cours de la période 1963-1968, les projets de normes ISO ont pris en charge l’utilisation de CR + LF ou de LF seule en tant que nouvelle ligne, alors que les projets d’ASA ne prenaient en charge que les versions CR + LF.

La séquence CR + LF était couramment utilisée sur de nombreux systèmes informatiques anciens qui avaient adopté des télétypes, généralement un ASR33, en tant que périphérique console, car cette séquence était nécessaire pour positionner ces imprimantes au début d'une nouvelle ligne. Sur ces systèmes, le texte était souvent composé de manière routinière pour être compatible avec ces imprimantes, car le concept de pilotes de périphérique masquant de tels détails matériels de l'application n'était pas encore bien développé; les applications devaient communiquer directement avec le télécopieur et suivre ses conventions.

La séparation des deux fonctions a masqué le fait que la tête d'impression ne pouvait pas revenir de l'extrême droite au début de la ligne suivante dans un délai d'un caractère. C'est pourquoi la séquence a toujours été envoyée avec le CR en premier. En fait, il était souvent nécessaire d'envoyer des caractères supplémentaires (CR ou NUL superflus, qui sont ignorés) pour que la tête d'impression ait le temps de se déplacer vers la marge gauche.

Même après que les télétypes aient été remplacés par des terminaux informatiques avec des débits en bauds plus élevés, de nombreux systèmes d'exploitation prenaient toujours en charge l'envoi automatique de ces caractères de remplissage, afin d'assurer la compatibilité avec les terminaux moins chers nécessitant plusieurs temps de caractères pour faire défiler l'affichage.

MS-DOS (1981) a adopté CR + LF de CP / M; L'utilisation de CR + LF par CP / M était logique pour l'utilisation de terminaux informatiques via des lignes série. Cette convention a été héritée par le dernier système d'exploitation Windows de Microsoft.

Le système d'exploitation Multics a commencé son développement en 1964 et utilisait uniquement la LF comme nouvelle ligne. Unix a suivi la pratique Multics et les systèmes ultérieurs ont suivi Unix.

Craige
la source
Sur l'ancien terminal clavier d'imprimante IBM 2741, le composant imprimante était une machine à écrire à bille de type à rebond IBM Selectric. Le passage en majuscule a entraîné la rotation de la balle, ce qui a pris plus de temps. Dans le code de caractère EBCDIC, les caractères majuscules avaient un bit en position 6. Ainsi, un blanc EBCDIC (0x40) était en majuscule! Si vous imprimez un long document (par exemple une thèse), vous pouvez considérablement accélérer la sortie en traduisant les blancs entre les mots minuscules en NUL, ou des blancs minuscules (ils ont utilisé un caractère différent, IL si la mémoire est suffisante, pour introduire les retards nécessaires, par exemple: , lors du retour ou de la tabulation).
George
5

Qu'en est-il des gens qui demandent "Pourquoi Unix peut- \nil le faire et pas Windows"? C'est une question si étrange.

  1. Le système d'exploitation n'a presque rien à voir avec cela. Il s’agit plus de savoir comment les applications, les bibliothèques, les protocoles et les formats de fichiers gèrent les choses. Hormis là où le système d'exploitation lit / écrit une configuration textuelle ou des commandes de ligne de commande, il n'y a aucun sens à mettre en cause le système d'exploitation.
  2. La plupart des applications Windows peuvent lire les deux \net \r\ntrès bien. Ils ont également produit \r\nafin que tout le monde soit heureux. Un programme ne fait pas simplement "faire" \nou \r\n- il accepte l’ un, l’autre ou les deux et produit l’ un, l’autre ou les deux.
  3. En tant que programmeur, cela ne devrait presque jamais vous déranger. Pratiquement chaque langue / plate-forme dispose des installations nécessaires pour écrire la ligne de fond correcte et lire de manière plus robuste. La seule fois que je l' ai eu à traiter le problème quand j'ai écrit un serveur HTTP - et ce fut parce qu'un certain navigateur (indice: le prochain navigateur le plus populaire après IE) a fait au \nlieu de la bonne \r\n .
  4. Une question beaucoup plus pertinente est la suivante: pourquoi tant d’applications Unix modernes ne produisent-elles que si elles \nsavent qu’il existe certains protocoles et programmes qui ne l’aiment pas?
Rei Miyasaka
la source
3
Autre question pertinente: puisque de nombreux protocoles ont été développés principalement sur des systèmes Unix, pourquoi n’ont-ils pas utilisé '\ n'?
David Thornley
@DavidThornley Parce que \ r \ n est plus susceptible de fonctionner sur plusieurs plates-formes (\ r pour les macs plus anciens, \ r \ n pour les fenêtres et \ n pour * nix).
Basic
4

La raison pour laquelle les conventions s’appliquent à leurs différents systèmes (\ n sur les systèmes de type Unix, \ r \ n sur Windows, etc.) est qu’une fois que vous avez sélectionné une convention, vous NE POUVEZ PAS la modifier sans détruire les fichiers de personnes. Et c'est généralement mal vu.

Des systèmes de type Unix ont été développés (à l’origine) avec différents modèles de télétype et, à un moment donné, une personne a décidé que l’équipement devait rapporter le poids du retour lorsqu’il effectuait un saut de ligne.

Windows venait de DOS, alors la question qui se pose à Windows est la suivante: pourquoi DOS utilise-t-il cette séquence cr / lf? Je suppose que cela a quelque chose à voir avec CP / M, où DOS a certaines de ses racines. Encore une fois, des modèles spécifiques de télétype peuvent avoir joué un rôle.

Michael Kohne
la source
Hum ... intéressant.
sukhbir
1
Pourquoi Windows ne peut-il pas gérer les lignes se terminant par \n, mais continuer à utiliser \r\npour le moment? S'ils le faisaient à partir de Windows XP, ils pourraient désormais commencer à enregistrer des fichiers avec \nau lieu de \r\n.
DisgruntledGoat
1
Windows n'a rien à voir avec cela. C'est la décision des applications, et la plupart des applications liront à la fois '\ n' et '\ r \ n' et écrivent '\ r \ n' - pour que tout le monde soit heureux.
Rei Miyasaka
2

Voici une réponse de la meilleure source - Microsoft. Pourquoi le terminateur de ligne est-il CR + LF?

Ce protocole remonte à l'époque des téléscripteurs. CR signifie "retour chariot" - le caractère de contrôle CR a renvoyé la tête d'impression ("chariot") à la colonne 0 sans faire avancer le papier. LF signifie "linefeed" - le caractère de contrôle LF a avancé le papier d'une ligne sans déplacer la tête d'impression. Ainsi, si vous souhaitez ramener la tête d'impression à la colonne zéro (prête à imprimer la ligne suivante) et faire avancer le papier (afin qu'elle imprime sur du papier vierge), vous avez besoin de CR et de LF.

Si vous consultez les divers documents de protocole Internet, tels que RFC 0821 (SMTP), RFC 1939 (POP), RFC 2060 (IMAP) ou RFC 2616 (HTTP), vous constaterez qu'ils spécifient tous CR + LF comme séquence de terminaison de ligne. La vraie question n'est donc pas "Pourquoi CP / M, MS-DOS et Win32 utilisent-ils CR + LF comme terminateur de ligne?" mais plutôt "Pourquoi d'autres personnes ont-elles choisi de différer de ces documents de normes et d'utiliser un autre terminateur de ligne?"

Unix a adopté Plain LF comme séquence de terminaison de ligne. Si vous examinez les options stty, vous verrez que l'option onlcr spécifie si un LF doit être remplacé par CR + LF. Si vous vous trompez de réglage, vous obtenez un texte en escalier, où

each
    line
        begins

où la ligne précédente s'est arrêtée. Ainsi, même unix, lorsqu'il est laissé en mode brut, nécessite CR + LF pour terminer les lignes. Le CR implicite avant LF est une invention Unix, probablement en tant qu’économie, puisqu’il économise un octet par ligne.

L'ascendance unix du langage C a transposé cette convention dans le standard du langage C, qui requiert uniquement "\ n" (qui code LF) pour terminer les lignes, ce qui impose aux bibliothèques d'exécution le fardeau de convertir les données de fichier brutes en lignes logiques.

Le langage C a également introduit le terme "nouvelle ligne" pour exprimer le concept de "terminateur de ligne générique". On me dit que le comité ASCII a changé le nom du caractère 0x0A en "newline" vers 1996, de sorte que le niveau de confusion a été encore augmenté.

Ondra Žižka
la source