279

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

4

9 に答える 9

435

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

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

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

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

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

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

于 2009-08-14T19:40:45.697 に答える
96

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、および多くのネットワークプロトコルは、依然として両方を期待しています:CRLF。
  • NLで標準化されたEBCDICを使用していた古いIBMシステム(ASCII文字セットにも存在しない文字)。Unicodeでは、NLはU+0085 NEXT LINEですが、実際のEBCDIC値は0x15です。

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

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

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

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

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

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

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

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

ハザ!移植性!

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

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

素晴らしい、それで特殊文字は何ですか?

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

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

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

これは多くの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
于 2012-03-03T19:34:43.887 に答える
11
  • "\r"=>戻る
  • "\ n" =>改行または改行(セマンティクス)

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

  • Dosは「\r\n」を使用してテキスト行を終了します。
  • 他のいくつかのマシンは「\r」だけを使用していました。(Commodore、Apple II、OSXより前のMacOSなど。)
于 2009-08-14T19:44:47.840 に答える
6

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

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

この出力を生成します:

hai

\n改行用です。

于 2012-11-17T03:57:30.097 に答える
4

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

于 2009-08-14T19:41:34.820 に答える
3

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

于 2009-08-14T19:41:27.347 に答える
3

@Jon Skeetの答えに加えて:

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

于 2009-08-14T19:42:34.007 に答える
1

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

于 2013-04-18T08:44:36.933 に答える
1

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

于 2014-10-09T08:25:24.043 に答える