\ rと\ nの違いは何ですか?


245

どのようにしている\r\n違いますか?それはUnix対Windows対Macと関係があると思いますが、それらがどのように異なり、正規表現で検索/一致するかは正確にはわかりません。


1
これには言語タグが必要です。言語によって、の解釈は異なり'\n'ます。
Adrian McCarthy 14年

回答:


383

彼らは別のキャラクターです。\rはキャリッジリターンで、\nラインフィードです。

「古い」プリンタで\rは、印刷ヘッドを行の先頭に戻し\n、紙を1行進めました。したがって、次の行で印刷を開始するには両方が必要でした。

明らかにそれは今やいくらか重要ではありませんが、コンソールによって\rは、行の先頭に移動して既存のテキストを上書きできる場合があります。

さらに重要なことに、Unix \nは行区切り文字として使用する傾向があります。Windows \r\nは行区切り文字として使用する傾向があり、Mac(OS 9まで)は行区切り文字として使用するために使用さ\rれていました。(Mac OS XはUnix-yなので、\n代わりに\r使用します。ただし、代わりにを使用する互換性の状況が存在する場合があります。)

詳細については、ウィキペディアの改行記事を参照してください

編集:これは言語依存です。たとえば、C#とJavaでは、\n 常に Unicode U + 000Aを意味し、ラインフィードとして定義されます。CおよびC ++では、意味はプラットフォーム固有であるため、水はやや濁っています。詳細についてはコメントを参照してください。


22
高齢者は+1。栄光の電子端末(それらの派手なCRTディスプレイの前のTTY)を直接制御するために使用される端末出力。したがって、キャリッジリターンと改行文字(Jon Skeetが述べたように、両方が必要になる場合があります)や\ a "bell"、\ b "backspace"( "delete"と混同しないでください)などのすばらしい成果物が得られます")、およびttyとの通信に必要な他のすべての制御文字。
erjiang

35
高齢者のための別の+1。WindowsコマンドプロンプトでCtrl + Gを押してEnterキーを押すと、PCスピーカーからビープ音が鳴ります。それは古くから残っています。
デイブカーリル

@Crappy Coding Guyは本当に?Vistaの場合、「 ''は内部コマンドまたは外部コマンドとして認識されません」と表示されます
Ponkadoodle 2010年

2
@AdrianMcCarthy:もちろん、質問は実際にはここではCまたはC ++を指定していません。たとえばC#では、改行であること\n 保証されています(セクション2.4.4.4)。もちろん、OPがプラットフォームを指定しているとよいでしょう。また、このレベルの詳細は、違いを尋ねるだけの人にとってはわかりにくいと思います。
Jon Skeet、2012年

2
@AdrianMcCarthy:しかし、少なくとも、C#とJavaで、それがある改行。これは、Unicodeによって「LINE FEED」(およびNEW LINE)と命名されたU + 000Aです。CとC ++の特殊なケースに言及するために編集しますが、これら特別なケースであり、逆ではないと本当に信じています
Jon Skeet

91

CおよびC ++では、\nは概念で\rあり、文字であり、\r\n(ほとんどの場合)移植性のバグです。

古いテレタイプについて考えてみてください。印字ヘッドは行と列に配置されています。印刷可能な文字をテレタイプに送信すると、現在の位置に文字が印刷され、ヘッドが次の列に移動します。(これは概念的にはタイプライターと同じですが、タイプライターは通常、プリントヘッドに対して用紙を移動します。)

現在の行を終了して次の行から始めたい場合は、2つの別々の手順を実行する必要がありました。

  1. 印字ヘッドを行頭に戻し、次に
  2. それを次の行に移動します。

ASCIIは、これらのアクションを2つの異なる制御文字としてエンコードします。

  • \x0D(CR)印字ヘッドを行の先頭に戻します。(UnicodeはこれをとしてエンコードしU+000D CARRIAGE RETURNます。)
  • \x0A(LF)印字ヘッドを次の行に移動します。(UnicodeはこれをとしてエンコードしU+000A LINE FEEDます。)

テレタイプと初期のテクノロジープリンターの時代には、これらが2つの別々の操作であるという事実を実際に利用していました。LFを付けずにCRを送信すると、すでに印刷した行の上に印刷できます。これにより、アクセント、太字、下線などの効果が可能になりました。一部のシステムでは、ハードコピーにパスワードが表示されないようにするために、数回オーバープリントされました。初期のシリアルCRT端末では、CRは画面上のテキストを更新するためにカーソル位置を制御する方法の1つでした。

しかし、ほとんどの場合、実際には次の行に行きたいだけです。一部のシステムでは、制御文字のペアを要求するのではなく、どちらか一方のみを許可しました。例えば:

  • Unixバリアント(Macの最新バージョンを含む)は、改行を示すためにLF文字のみを使用します。
  • 古い(OSX以前の)Macintoshファイルでは、CR文字だけを使用して改行を示していました。
  • VMS、CP / M、DOS、Windows、および多くのネットワークプロトコルは、CR LFを両方とも期待しています。
  • NL(ASCII文字セットには存在しない文字)で標準化されたEBCDICを使用していた古いIBMシステム。Unicodeでは、NLはU+0085 NEXT LINEですが、実際のEBCDIC値は0x15です。

異なるシステムが異なる方法を選択したのはなぜですか?普遍的な基準がなかったからです。キーボードがおそらく「Enter」と言っているところで、古いキーボードは「Return」と言っていましたが、これはキャリッジリターンの略でした。実際、シリアル端末でReturnキーを押すと、実際にはCR文字が送信されます。テキストエディタを作成している場合、ターミナルから入力した文字をそのまま使用するのは魅力的です。おそらくそれが、古いMacがCRだけを使用した理由です。

これで標準ができたので、改行を表す方法はにもあります。世の中で非常にまれですが、Unicodeには次のような新しい文字があります。

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

Unicodeが登場する前から、プログラマーは、基礎となる文字セットを気にすることなく、最も有用な制御コードのいくつかを表す簡単な方法を求めていました。Cには、制御コードを表すためのいくつかのエスケープシーケンスがあります。

  • \a (アラート用)テレタイプのベルを鳴らすか、端末のビープ音を鳴らす
  • \f (改ページ用)次ページの先頭に移動
  • \t (タブの場合)印刷ヘッドを次の水平タブ位置に移動します

(このリストは意図的に不完全です。)

このマッピングはコンパイル時に行われます-コンパイラは\a、ベルを鳴らすために使用されるすべての魔法の値を確認して配置します。

これらのニーモニックのほとんどは、ASCII制御コードと直接相関していることに注意してください。たとえば、\aにマップします0x07 BELます。ホスト文字セットにASCII以外のもの(EBCDICなど)を使用するシステム用にコンパイラを作成できます。特定のニーモニックを持つ制御コードのほとんどは、他の文字セットの制御コードにマップできます。

フザー!携帯性!

よくほとんど。Cではprintf("\aHello, World!");、ベル(またはビープ)を鳴らしてメッセージを出力するように書くことができます。しかし、次の行に何かを印刷したい場合でも、ホストプラットフォームが出力の次の行に移動するために何が必要かを知る必要があります。CR LF?CR?LF?NL?他に何か?移植性のためにそんなに。

Cには、バイナリとテキストの2つのI / Oモードがあります。バイナリモードでは、送信されるデータはすべてそのまま送信されます。しかし、テキストモードでは、ホストプラットフォームが新しい行に必要なもの(またはその逆)に特殊文字を変換するランタイム変換があります。

すばらしいので、特別なキャラクターは何ですか?

それも実装に依存しますが、実装に依存しない方法で指定できます\n。通常、「改行文字」と呼ばれます。

これは微妙ですが重要なポイントです。 コンパイル時実装定義の文字値に\nマップされます(テキストモードの場合)は、実行時に、基盤となるプラットフォームが移動するために必要な実際の文字(または文字シーケンス)に再度マップされます。次の行へ。

\n2つのマッピングが関係しているため、他のすべてのバックスラッシュリテラルとは異なります。この2段階のマッピングは、とは\n大幅に異なり\rます。これは、コンパイル時のCR(または、基になる文字セットが最も似ている制御コード)へのコンパイル時のマッピングです。

これは多くのCおよびC ++プログラマーをつまずかせます。それらの100をポーリングする場合、少なくとも99 \nはラインフィードを意味します。これは完全に真実ではありません。ほとんど(おそらくすべて)のCおよびC ++の実装では、LFをの魔法の中間値として使用しますが\n、これは実装の詳細です。コンパイラが別の値を使用することは現実的です。実際、ホストの文字セットがASCIIのスーパーセットでない場合(たとえば、EBCDICの場合)は、\nほぼ確実にLFにはなりません。

したがって、CおよびC ++では:

  • \r 文字通りキャリッジリターンです。
  • \n実行時にホストプラットフォームの改行セマンティクスとので(テキストモードで)変換される魔法の値です。
  • \r\nほとんどの場合、移植性のバグです。テキストモードでは、これはCRに変換され、その後にプラットフォームの改行シーケンスが続きます-おそらく意図したものではありません。バイナリモードでは、これはCRに変換され、その後にLF ではない可能性がある魔法の値が続きます。
  • \x0AASCII LFを示す最もポータブルな方法ですが、それはバイナリモードでのみ行いたいものです。ほとんどのテキストモード実装は、それをのように扱います\n

Pythonで<textarea>入力を分割する方法を理解しようとしているときにこの投稿に出くわし、\r\n実際に、行を個別のリスト要素に適切に分割できる唯一の方法です。これが変なHTMLアーティファクトなのか、それともPythonがrequestオブジェクトから文字列を取り込む方法に関係しているのか疑問に思います。
Pat Jones、

11
  • "\ r" => Return
  • "\ n" =>改行または改行(セマンティクス)

  • Unixベースのシステムでは、「\ n」だけを使用してテキスト行を終了します。

  • Dosは "\ r \ n"を使用してテキスト行を終了します。
  • 他の一部のマシンは「\ r」だけを使用していました。(コモドール、Apple II、OS Xより前のMac OSなど)

5

\r 行の先頭を指すために使用され、そこからテキストを置き換えることができます。例:

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

この出力を生成します:

hai

\n 改行用です。


4

つまり、\ rにはASCII値13(CR)があり、\ nにはASCII値10(LF)があります。Macは行区切り文字としてCRを使用します(少なくとも以前はそうでしたが、現代のMacではわかりません)。* nixはLFを使用し、Windowsは両方(CRLF)を使用します。


1
Mac OS XシステムはデフォルトでLFを使用します(BSD Unixに基づいているため)。
dreamlax

3

@ジョンスキートの答えに加えて:

従来、Windowsは\ r \ n、Unix \ n、Mac \ rを使用していましたが、新しいMacはUNIXベースであるため、\ nを使用しています。


2

C#では、文字列で\ r \ nを使用していることがわかりました。


2

\ rはキャリッジリターンです。\ nは改行(改行)です...それぞれの意味はOSによって異なります。Cの「\ n」と「\ r \ n」の違いの詳細については、この記事をお読みください。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.