Quelle est la différence entre r et n?

En quoi r et n sont-ils différents? Je pense que cela a quelque chose à voir avec Unix vs. Windows vs. Mac, mais je ne suis pas sûr exactement comment ils sont différents, et lequel rechercher/match dans les expressions rationnelles.

208
demandé sur Artemis 2009-08-14 23:37:23

9 réponses

Ce sont des personnages différents. \r est retour chariot, et \n est saut de ligne.

Sur les "anciennes" imprimantes, \r a renvoyé la tête d'impression au début de la ligne, et \n a avancé le papier d'une ligne. Les deux étaient donc nécessaires pour commencer à imprimer sur la ligne suivante.

De toute évidence, c'est un peu hors de propos maintenant, bien que selon la console, vous puissiez toujours utiliser \r pour passer au début de la ligne et écraser le texte existant.

Plus surtout, Unix, a tendance à utiliser \n comme un séparateur de ligne; Windows a tendance à utiliser \r\n comme un séparateur de ligne et Mac (jusqu'à OS 9) utilisé utiliser \r comme séparateur de ligne. (Mac OS X est Unix-y, donc utilise \n à la place; il peut y avoir des situations de compatibilité où \r est utilisé à la place.)

Pour plus d'informations, consultez l'article Wikipedia newline.

EDIT: ceci est sensible à la langue. En C# et en Java, par exemple, \n toujours signifie Unicode U + 000A, qui est défini comme saut de ligne. En C et c++ , l'eau est un peu plus boueuse, car la signification est spécifique à la plate-forme. Voir les commentaires pour plus de détails.

328
répondu Jon Skeet 2012-03-03 21:46:49

En C et C++, \n est un concept, \r est un personnage, et \r\n est (presque toujours) une portabilité bug.

Pensez à un vieux télétype. La tête d'impression est positionnée sur une ligne et dans une colonne. Lorsque vous envoyez un caractère imprimable au télétype, il imprime le caractère à la position actuelle et déplace la tête vers la colonne suivante. (C'est conceptuellement la même chose qu'une machine à écrire, sauf que les machines à écrire déplaçaient généralement le papier par rapport à l'impression tête.)

Lorsque vous vouliez terminer la ligne en cours et commencer sur la ligne suivante, vous deviez faire deux étapes distinctes:

  1. replacez la tête d'impression au début de la ligne, puis
  2. déplacer vers la ligne suivante.

ASCII Code ces actions sous la forme de deux caractères de contrôle distincts:

  • \x0D (CR) ramène la tête d'impression au début de la ligne. (Unicode code comme U+000D CARRIAGE RETURN.)
  • \x0A (LF) déplace la tête d'impression à la ligne suivante. (Unicode code comme U+000A LINE FEED.)

À l'époque des télétypes et des premières imprimantes technologiques, les gens ont en fait profité du fait qu'il s'agissait de deux opérations distinctes. En envoyant un CR sans le suivre par un LF, vous pouvez imprimer sur la ligne que vous avez déjà imprimée. Cela a permis des effets tels que les accents, le type gras et le soulignement. Certains systèmes ont surimprimé plusieurs fois pour empêcher les mots de passe d'être visibles sur papier. Au début de la série CRT terminaux, CR était l'un des moyens de contrôler la position du curseur afin de mettre à jour le texte déjà sur l'écran.

Mais la plupart du temps, tu voulais juste passer à la ligne suivante. Plutôt que d'exiger la paire de caractères de contrôle, certains systèmes n'autorisaient que l'un ou l'autre. Par exemple:

  • les variantes Unix (y compris les versions modernes de Mac) utilisent juste un caractère LF pour indiquer une nouvelle ligne.
  • les anciens fichiers Macintosh (pré-OSX) n'utilisaient qu'un caractère CR pour indiquez une nouvelle ligne.
  • les machines virtuelles, CP/M, DOS, Windows et de nombreuxprotocoles réseau attendent toujours les deux: CR LF.
  • anciens systèmes IBM qui utilisaient EBCDIC standardisés sur NL-un caractère qui n'existe même pas dans le jeu de caractères ASCII. En Unicode, NL est U+0085 NEXT LINE, mais la valeur EBCDIC réelle est 0x15.

Pourquoi différents systèmes ont-ils choisi des méthodes différentes? Tout simplement parce qu'il n'y avait pas de norme universelle. Où votre clavier dit probablement "entrée", plus les claviers utilisés pour dire "retour", qui était l'abréviation de retour chariot. En fait, sur un terminal série, appuyer sur Retour envoie réellement le caractère CR. Si vous écrivez un éditeur de texte, il serait tentant d'utiliser ce caractère tel qu'il est entré depuis le terminal. C'est peut-être pourquoi les anciens Mac utilisaient juste CR.

Maintenant que nous avons normes, il existe plus façons de représenter les sauts de ligne. Bien qu'extrêmement rare dans la nature, Unicode a de nouveaux caractères comme:

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

Avant même L'arrivée D'Unicode, les programmeurs voulaient des moyens simples de représenter certains des codes de contrôle les plus utiles sans se soucier du jeu de caractères sous-jacent. C a plusieurs séquences d'échappement pour représenter les codes de contrôle:

  • \a (Pour alerte) qui sonne la cloche de télétype ou fait bip du terminal
  • \f (pour le flux de formulaire) qui se déplace au début du suivant page
  • \t (Pour tab) qui déplace la tête d'impression à la position horizontale suivante de tabulation

(cette liste est intentionnellement incomplète.)

Ce mappage se produit à au moment de la compilation--le compilateur voit \a et met la valeur magique utilisée pour sonner la cloche.

Notez que la plupart de ces mnémoniques ont des corrélations directes avec les codes de contrôle ASCII. Par exemple, \a correspondrait à 0x07 BEL. Un compilateur peut être écrit pour un système qui utilise autre chose que ASCII pour le jeu de caractères hôte (par exemple, EBCDIC). La plupart des codes de contrôle qui avait des mnémoniques pourrait être mappés à des codes de contrôle dans d'autres jeux de caractères.

Huzzah! La portabilité!

Enfin, presque. En C, je pourrais écrire printf("\aHello, World!"); qui sonne la cloche (ou émet un bip) et émet un message. Mais si je voulais ensuite imprimer quelque chose sur la ligne suivante, j'aurais toujours besoin de savoir ce que la plate-forme hôte nécessite pour passer à la ligne de sortie suivante. CR LF? CR? LF? NL? Quelque chose d'autre? Tant pour des raisons de portabilité.

C a deux modes pour les e / s: binaire et texte. En mode binaire, les données envoyées sont transmises telles quelles. Mais en mode texte, il y a une traduction run-time qui convertit un caractère spécial en tout ce dont la plate-forme hôte a besoin pour une nouvelle ligne (et vice versa).

Super, alors quel est le caractère spécial?

Eh bien, cela dépend aussi de l'implémentation, mais il existe un moyen indépendant de l'implémentation de spécifier il: \n. Il est généralement appelé le "caractère de nouvelle ligne".

C'est un point subtil mais important: \n est mappé à au moment de la compilation à une valeur de caractère définie par l'implémentation qui (en mode texte) est ensuite mappé à nouveau à au moment de l'exécution au caractère réel (ou à la séquence de caractères) requis par la plate-forme sous-jacente pour passer à la ligne suivante.

\n est différent de tous les autres littéraux antislash car il y en a deux les mappages de cause. Ce mappage en deux étapes rend \n significativement différent de even \r, qui est simplement un mappage à la compilation vers CR (ou le code de contrôle le plus similaire quel que soit le jeu de caractères sous-jacent).

Cela déclenche de nombreux programmeurs C et c++. Si vous deviez interroger 100 d'entre eux, au moins 99 vous diront que \n signifie saut de ligne. Ce n'est pas tout à fait vrai. La plupart (peut-être toutes) les implémentations C et c++ utilisent LF comme valeur intermédiaire magique pour \n, mais c'est un détail d'implémentation. Il est possible pour un compilateur d'utiliser une valeur différente. En fait, si le jeu de caractères hôte n'est pas un sur-ensemble D'ASCII (par exemple, S'il s'agit D'EBCDIC), alors \n ne sera presque certainement pas LF.

Donc, en C et c++:

  • \r est littéralement un retour chariot.
  • \n est une valeur magique qui est traduite (en mode texte) à au moment de l'exécution vers/depuis la sémantique de nouvelle ligne de la plate-forme hôte.
  • \r\n est presque toujours une portabilité bogue. En mode texte, cela est traduit en CR suivi de la séquence de nouvelle ligne de la plate-forme-probablement pas ce qui est prévu. En mode binaire, cela est traduit en CR suivi d'une valeur magique qui pourrait ne pas être LF-peut-être pas ce qui est prévu.
  • \x0A est le moyen le plus portable d'indiquer un LF ASCII, mais vous ne voulez le faire qu'en mode binaire. La plupart des implémentations en mode texte traiteront cela comme \n.
82
répondu Adrian McCarthy 2015-04-12 16:38:20
  • "\r " = > retour
  • "\n " = > saut de ligne ou saut de ligne (sémantique)

  • Les systèmes basés sur Unix utilisent juste un "\n " pour terminer une ligne de texte.

  • Dos utilise "\r \ n" pour terminer une ligne de texte.
  • certaines autres machines utilisaient juste un "\ r". (Commodore, Apple II, Mac OS avant OS X, etc..)
9
répondu NoMoreZealots 2009-08-14 20:37:21

En bref, \r a la valeur ASCII 13 (CR) et \n a la valeur ASCII 10 (LF). Mac utilise CR comme délimiteur de ligne (au moins, il l'a fait avant, Je ne suis pas sûr pour les Mac modernes), * nix utilise LF et Windows utilise les deux (CRLF).

4
répondu Josip Medved 2009-08-14 19:41:34

\r est utilisé pour pointer vers le début d'une ligne et peut remplacer le texte à partir de là, par exemple,

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

Produit cette sortie:

hai

\n est pour la nouvelle ligne.

4
répondu DAYA PHILIP 2012-11-17 04:27:49

En plus de la réponse de @Jon Skeet:

Traditionnellement, Windows utilise \r \n, Unix \N et Mac \R, mais les nouveaux Mac utilisent \ N car ils sont basés sur unix.

3
répondu Greg 2009-08-14 19:42:34

En C# j'ai trouvé qu'ils utilisent \r \ n dans une chaîne.

2
répondu wesley 2013-04-18 08:44:36

\r est retour chariot; \n est nouvelle ligne (saut de ligne)... cela dépend du système d'exploitation quant à ce que chacun signifie. Lisez cet article pour en savoir plus sur la différence entre '\N' et '\r\n' ... en C.

2
répondu Nathan Loding 2016-07-27 11:49:09

\ r utilisé pour le retour chariot. (La valeur ASCII est 13) \n utilisé pour la nouvelle ligne. (La valeur ASCII est 10)

1
répondu Manjeet Kumar 2014-10-09 08:25:24