web-dev-qa-db-ja.com

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

\r\nはどう違うのですか?私はそれがUnix対Windows対Macと関係があると思うが、私はそれらがどう違うのか、そして正規表現の中でどれを検索するか/マッチするのか正確にはわからない。

225
Sam Lee

彼らは違うキャラクターです。 \rはキャリッジリターン、\nは改行です。

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

コンソールによっては\rを使用して行の先頭に移動して既存のテキストを上書きすることができる場合もありますが、明らかにこれは多少無関係です。

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

詳しくは、 Wikipediaの改行記事 を参照してください。

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

354
Jon Skeet

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。
  • EBCDIC NLで標準化された古いIBMシステム-ASCII文字セットには存在しない文字。 Unicodeでは、NLはU+0085 NEXT LINEですが、実際のEBCDIC値は0x15です。

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

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

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

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

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

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

このマッピングはcompile-timeで行われます。コンパイラは\aを見て、ベルを鳴らすのに使用されるマジック値を入れます。

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

ハザ!移植性!

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

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

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

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

これは微妙ですが重要なポイントです:\ncompile timeにマッピングされますimplementation-defined文字値(テキストモードで)はruntimeで実際の文字(または文字)基になるプラットフォームが次の行に移動するために必要です。

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

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

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

  • \rは文字通りキャリッジリターンです。
  • \nは、ホストプラットフォームの改行セマンティクスとの間でrun-timeで(テキストモードで)変換されるマジック値です。
  • \r\nはほとんどの場合、移植性のバグです。テキストモードでは、これはCRに翻訳され、その後にプラットフォームの改行シーケンスが続きます。バイナリモードでは、これはCRに変換され、LFではない可能性のあるマジック値が続きます。
  • \x0Aは、ASCII LFを示す最も移植性の高い方法ですが、バイナリモードでのみこれを行います。ほとんどのテキストモードの実装は、\nのようにそれを扱います。
89
Adrian McCarthy
  • "\ r" =>戻る
  • "\ n" =>改行または改行(セマンティクス)

  • Unixベースのシステムでは、テキスト行の終わりに "\ n"だけを使います。

  • Dosは "\ r\n"を使ってテキストの行を終わらせます。
  • 他のいくつかのマシンは "\ r"だけを使っていました。 (Commodore、Apple II、OS Xより前のMac OSなど)
10
NoMoreZealots

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

4
Josip Medved

\rは行の始まりを指すのに使われ、そこからテキストを置き換えることができます。

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

この出力を生成します:

hai

\nは改行用です。

4
DAYA PHILIP

@Jon Skeetの回答に加えて:

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

3
Greg

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

2
Nathan Loding

c#で私は彼らが文字列で\ r\nを使用することがわかりました。

2
wesley

キャリッジリターンに使用します。 (ASCII値は13)\ n改行に使用されます。 (ASCII値は10です)

1
Manjeet Kumar