web-dev-qa-db-fra.com

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

Oui oui, je sais 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 agréable en théorie, mais ma question est pourquoi ? Pourquoi le caractère de retour chariot est supplémentaire dans Windows? Si UNIX peut le faire dans \n pourquoi faut-il à Windows deux caractères pour ce faire?

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

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

Pourquoi l'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 que c'est répondu aujourd'hui.

Merci pour votre temps.

108
sukhbir

Rétrocompatibilité.

Windows est rétrocompatible avec MS-DOS (de manière agressive, même) et MS-DOS a utilisé la convention CR-LF parce que MS-DOS était compatible avec CP/M-80 (un peu par accident) qui a utilisé la convention CR-LF parce que cela était comment vous conduisiez une imprimante (parce que les imprimantes étaient à l'origine des machines à écrire contrôlées par ordinateur).

Les imprimantes ont une commande distincte pour déplacer le papier d'une ligne vers une nouvelle ligne et une commande distincte pour ramener le chariot (où le papier a été monté) vers la marge gauche.

Voilà pourquoi. Et, oui, c'est une gêne, mais cela fait partie de l'accord qui a permis à MS-DOS de gagner CP/M, et à Windows 95 de gagner toutes les autres interfaces graphiques au-dessus de DOS, et Windows XP pour succéder à Windows 98.

(Remarque: les imprimantes laser modernes ont toujours ces commandes car elles sont également rétrocompatibles avec les imprimantes antérieures - HP en particulier le fait bien)

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

133
user1249

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

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

\n est une nouvelle ligne, qui déplace votre papier d'une ligne.

Faire un seul de ces éléments sur une machine à écrire vous mettrait au mauvais endroit pour commencer à écrire une nouvelle ligne de texte.

Lorsque les ordinateurs sont apparus, je suppose que certaines personnes ont conservé l'ancien modèle, mais d'autres ont réalisé que ce n'était pas nécessaire et ont encapsulé une nouvelle ligne complète en un seul personnage.

21
Matt Ellen

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 ex.

for i in {1..100}
do
    printf "\rLoading... %d%%" $i
    sleep 0.01
done
echo
9
Daniel Lubarov

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

Retour chariot signifie "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, car cela avait du sens pour les lignes série.

Unix a copié sa convention\n parce que Multics l'a fait.

Je soupçonne que si vous creusez assez loin, vous trouverez un désaccord politique entre les implémenteurs!

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

7
Frank Shearar

Histoire du caractère Newline (Wikipedia):

ASCII a été développé simultanément par l'ISO et l'ASA, l'organisation prédécesseur de l'ANSI. Au cours de la période 1963-1968, les projets de normes ISO ont soutenu l'utilisation de CR + LF ou LF seul comme nouvelle ligne, tandis que les projets ASA ne prenaient en charge que CR + LF.

La séquence CR + LF était couramment utilisée sur de nombreux premiers systèmes informatiques qui avaient adopté des machines de téléscripteur, généralement un ASR33, comme périphérique de 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ériques masquant ces détails matériels à l'application n'était pas encore bien développé; les applications devaient parler directement à la machine de téléscripteur et suivre ses conventions.

La séparation des deux fonctions dissimulait le fait que la tête d'impression ne pouvait pas revenir de l'extrême droite au début de la ligne suivante en un seul 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 étrangers, qui sont ignorés) pour donner à la tête d'impression le temps de se déplacer vers la marge gauche.

Même après que les télétypes ont é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, pour une compatibilité avec les terminaux moins chers qui nécessitaient plusieurs temps de caractères pour faire défiler l'affichage.

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

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

6
Craige

Qu'est-ce que les gens demandent "pourquoi Unix peut-il faire \n et pas Windows "? C'est une question tellement étrange.

  1. L'OS n'a presque rien à voir avec cela. Cela dépend davantage de la façon dont 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 des commandes de configuration ou de ligne de commande basées sur du texte, cela n'a aucun sens de mettre le système d'exploitation en défaut.
  2. La plupart des applications Windows peuvent lire les deux \n et \r\n ça va. Ils produisent également \r\n pour que tout le monde soit content. Un programme ne fait pas simplement "faire" non plus \n ou \r\n - il accepte l'une, l'autre ou les deux, et les sorties l'un, l'autre ou les deux.
  3. En tant que programmeur, cela ne devrait vraiment jamais vous déranger. Pratiquement chaque langue/plate-forme dispose d'installations pour écrire la ligne de fin correcte et lire de la manière la plus robuste. La seule fois où j'ai eu à résoudre le problème, c'est quand j'ai écrit un serveur HTTP - et c'était parce qu'un certain navigateur (indice: le prochain navigateur le plus populaire après IE) faisait \n au lieu de la bonne\r\n.
  4. Une question beaucoup plus pertinente est la suivante: pourquoi tant d'applications Unix modernes ne produisent-elles que \n sachant parfaitement qu'il existe des protocoles et des programmes qui ne l'aiment pas?
5
Rei Miyasaka

La raison pour laquelle les conventions tiennent sur 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 choisi une convention, vous NE POUVEZ PAS la changer sans casser un tas de fichiers. Et c'est généralement mal vu.

Des systèmes de type Unix ont été développés (très tôt) à l'aide de divers modèles de téléscripteur, et à un moment donné, quelqu'un a décidé que l'équipement devait être renvoyé lorsqu'il effectuait un saut de ligne.

Windows est venu de DOS, donc pour Windows la question est vraiment: pourquoi DOS a-t-il utilisé 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.

4
Michael Kohne

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

Ce protocole remonte à l'époque des téléscripteurs. CR signifie "chariot retour" - 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 "saut de ligne" - le caractère de contrôle LF a avancé le papier d'une ligne sans déplacer la tête d'impression. Donc, si vous vouliez retourner la tête d'impression à colonne zéro (prêt à imprimer la ligne suivante) et avancez le papier (pour qu'il imprime sur du papier frais), vous avez besoin à la fois de CR et de LF.

Si vous accédez aux divers documents de protocole Internet, tels que RFC 0821 (SMTP), RFC 1939 (POP), RFC 2060 (IMAP) ou RFC 2616 (HTTP), vous verrez 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 s'écarter 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 regardez les options stty, vous verrez que l'option onlcr spécifie si un LF doit être changé en CR + LF. Si vous obtenez ce paramètre incorrect, vous obtenez un texte d'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, car il enregistre un octet par ligne.

L'ascendance unix du langage C a transporté cette convention dans la norme du langage C, qui ne nécessite que "\ n" (qui code LF) pour terminer les lignes, imposant aux bibliothèques d'exécution la charge de convertir les données brutes des fichiers 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, donc le niveau de confusion a été augmenté encore plus.

2
Ondra Žižka