「\ n」と「\ r \ n」の違い


99

はい、はい、'\n'UNIXには改行を書くのに対して、Windowsには次の2つの文字シーケンスがあります'\r\n'。これはすべて理論上非常に良いことですが、私の質問はなぜですか?Windowsで復帰文字が余分なのはなぜですか?UNIXがそれを行うことができる場合\n、Windowsがこれを行うのに2文字を要するのはなぜですか?

私はデビッド・ビーズリーのPython本を読んでいて、彼はこう言っています:

たとえば、Windowsでは、文字「\ n」を書き込むと、実際には2文字のシーケンス「\ r \ n」が出力されます(ファイルを読み戻すと、「\ r \ n」は単一の「\ n」に変換されますキャラクター)。

なぜ余分な努力が必要なのですか?

私は正直になります。私は長い間違いを知っていましたが、なぜ尋ねるのを悩ませたことはありません。今日はそれが答えられることを願っています。

御時間ありがとうございます。


5
また、Windowsだけがを使用するわけではないことに注意してください\r\n。また、ほとんどのテキストベースのインターネットプロトコル(SMTP、HTTPなど)でも、Windowsとほぼ同じ理由(つまり履歴)で使用されています。
ディーンハーディング

3
また、Javaでフォーマット文字列(System.out.printf()またはString.format())を使用する場合%nは、OSの互換性のためにCRLFとして使用してください。\n非推奨です。
ゲイリーロウ

\n\r何回か見ました。(NetWareからのものだと思います。)
grawity


1
実際にCRLFを必要とするWindowsプログラムはほとんどありません。CRLFがデフォルトかもしれませんが、ほとんどすべてがLFを自動検出して使用します。すべての新しいファイルにLFを使用するようにWindows上のすべてのテキストエディターを構成しましたが、実際には問題ではありません。
ケビン

回答:


124

下位互換性。

WindowsはMS-DOSと下位互換性があり(積極的にもそうです)、MS-DOSはCR-LF規則を使用していたCP / M-80(やや偶然)と互換性があるため、MS-DOSはCR-LF規則を使用しましたプリンターを運転する方法でした(プリンターはもともとコンピューター制御のタイプライターだったため)。

プリンタには、用紙を1行上に移動して新しい行に移動する個別のコマンドと、キャリッジ(用紙がマウントされた場所)を左マージンに戻す個別のコマンドがあります。

それが理由です。そして、はい、それは迷惑ですが、MS-DOSがCP / Mを勝ち取り、Windows 95がDOSの上にある他のすべてのGUIを勝ち取り、Windows XPが引き継ぐことを可能にするパッケージ取引の一部です。 Windows 98から。

(注:最近のレーザープリンターには、以前のプリンターとの下位互換性があるため、これらのコマンドがまだあります。特にHPはこれをうまく行います)

:タイプライターに慣れていない人のために、ここでのタイピングが行われたかを示すビデオです http://www.youtube.com/watch?v=LJvGiU_UyEQが。紙が最初に上に移動してから、キャリッジが戻されることに注意してください。たとえそれが単純な動きで起こったとしてもです。ディンはタイピストに終わりが近づいていることを通知し、その準備をしました。


3
Unixは、\ nが昔のプリンターでしか機能しなかったのはどうしてですか?タイプライタータイプのプリンターに接続されたUnixコンソールがあったと思いますか?
センチルクマラン

3
@ Senthil、Unixでは、改行文字はエンドドライバーによって変換されます。これは、設計上の異なる決定です。

2
@Senthil、正確には、Unixではプリンターと端末はオペレーティングシステムで抽象化され、それらの記述はデバイス用に生成されるバイトシーケンスを決定します。CP / Mには、実行中のプログラムにすべてを引き継ぐような抽象化はありませんでした。これは、すべてのプログラムがこれを必要としなかったためです。CP / Mは16 キロバイトシステム用に設計されたことを思い出してください。

1
「したがって、おそらく世界で最も先進的な輸送システムであるものの主要な設計上の特徴は、もともと馬のお尻の幅によって決まりました。」そのため、ソフトウェアでも同様です。astrodigital.org/space/stshorse.html
ライアンミケーラ

1
@Ryan、都市伝説。暴かsnopes.com/history/american/gauge.htm

20

私が知る限り、これはタイプライターの時代を思わせます。

\r キャリッジリターンです。ページ上で入力している場所を左に移動します(それが文化の場合は右に移動します)

\n 用紙を1行上に移動する新しい行です。

タイプライターでこれらの1つだけを実行すると、間違った場所に移動して新しい行のテキストを書き始めることになります。

コンピューターが登場したとき、一部の人々は古いモデルを保持していましたが、他の人はそれが必要ではないと気づき、完全な改行を1つのキャラクターとしてカプセル化しました。


7
では、なぜWindowsはまだそれに固執するのですか?
スフビル

8
下位互換性。今すぐ変更すると、テキスト文書がいくつ壊れるのか想像してみてください
マットエレン

4
厳密に言えば、ここの「奇数」はunixoidの「改行のみを使用」であり、最初に保存された文字数を抑えるために行われます(CR LFへの変換はターミナルドライバーで行われ、それは「onlcr」フラグです)それは出力のためにそれを制御します
Vatine

3
Windowsには、同じ行末を持つDOSという名前の先行バージョンがありました。Windowsは互換性を維持しました。DOSには前身、つまりCP / Mがありました。CRLFも使用しました。DOSは互換性を維持しました。CP / Mの開発は、DEC TOPSの影響を受けました。そして、あなたは彼らが使用したどのラインエンドを推測することができます。:-)互換性は多くを説明します。
Mnementh

5
OK、しかしなぜメモ帳はまだ「\ n」行末を認識しないのですか?
dan04

8

これが一般的な知識であるかどうかはわかりませんが、CRは最新の端末エミュレーターによってまだ理解されていることに注意してください。

$ printf "hey world\rsup\n"
sup world

進行状況インジケーターに便利です。たとえば

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

1
古いIBMラインプリンター(1403など)では、慣例として、ラインバッファーの最初の文字をキャリッジ制御文字として扱いました。空白は、1行進めて印刷することを意味します。Plusは、スペースを省略することを意味し、下線などに使用されました。ゼロはダブルスペースを意味し、マイナスはトリプルスペースを意味します。次のページの上部に「1」のスペースを空け、他の数字をユーザー定義の垂直位置に進めます(事前印刷フォームの入力に使用)。
ジョージ

7

歴史的に、ラインフィードとは、プラテン(入力するローラー)が1行回転し、次の行にテキストが表示されることを意味していましたが、次の列に表示されていました。

キャリッジリターンとは、「入力したビットを行の先頭に戻す」ことを意味します。

WindowsはCR + LFを使用します。これは、MS-DOSが使用したため、CP / Mが使用したためです。

UNIXは、Multicsが行ったため、\ n規則をコピーしました。

深く掘り下げてみると、実装者の間で政治的な意見の相違が見られるでしょう。

(Macの慣例では、CRを使用して行を分離するだけである(または以前は使用されていた)余分な楽しいビットは省略しました。現在、Unicodeには独自の行区切り文字U + 2028もあります!)


うわー!Macを知らなかった...
マイケルK

あなたが政治的な意見の相違を見つけるかどうかはわかりません。また、同様のことを独自に行っている人を見つける可能性もあります。
デビッドソーンリー

1
さまざまな標準化団体が関与する場合 政治的な理由を見つけられないことに驚かされるでしょう!
フランクシェラー

6

改行文字の歴史(ウィキペディア):

ASCIIは、ISOとANSIの前身であるASAによって同時に開発されました。1963年から1968年の間に、ISOドラフト標準はCR + LFまたはLFのみを改行として使用することをサポートしていましたが、ASAドラフトはCR + LFのみをサポートしていました。

CR + LFシーケンスは、コンソールデバイスとしてテレタイプマシン(通常はASR33)を採用していた多くの初期のコンピューターシステムで一般的に使用されていました。これらのシステムでは、アプリケーションからそのようなハードウェアの詳細を隠すデバイスドライバーの概念がまだ十分に開発されていないため、テキストはこれらのプリンターと互換性があるように定型的に構成されることがよくありました。アプリケーションは、テレタイプマシンと直接対話し、その規則に従う必要がありました。

2つの機能の分離により、印字ヘッドが1文字の時間で右端から次の行の先頭に戻ることができなかったという事実が隠されました。これが、シーケンスが常に最初にCRで送信された理由です。実際、プリントヘッドが左マージンに移動する時間を与えるために、余分な文字(無視されるCRまたはNUL)を追加で送信する必要がしばしばありました。

テレタイプがより高いボーレートのコンピューター端末に置き換えられた後でも、多くのオペレーティングシステムは、ディスプレイをスクロールするのに複数の文字時間を必要とする安価な端末との互換性のために、これらの塗りつぶし文字の自動送信をサポートしていました。

MS-DOS(1981)はCP / MのCR + LFを採用しました。CP / MでのCR + LFの使用は、シリアル回線経由でコンピューター端末を使用するのに意味がありました。この規則は、後のMicrosoftのWindowsオペレーティングシステムに継承されました。

Multicsオペレーティングシステムは1964年に開発を開始し、LFのみを改行として使用しました。UnixはMulticsの慣習に従い、後のシステムはUnixに従いました。


古いIBM 2741プリンターキーボードターミナルでは、プリンターコンポーネントはIBM Selectricバウンスタイプボールタイプライターでした。大文字に変更すると、ボールが回転し、余分な時間がかかりました。EBCDIC文字コードでは、大文字の位置6に1ビットがありました。したがって、EBCDICの空白(0x40)は大文字でした!長いドキュメント(論文など)を印刷する場合、小文字の単語間の空白をNULまたは小文字の空白(メモリが役立つ場合は異なる文字、ILを使用して、必要な遅延を導入するなど) 、戻るときまたはタブ移動するとき)。
ジョージ

5

\nWindowsではなくUnixができる理由」を尋ねる人々とは何ですか?とても奇妙な質問です。

  1. OSはほとんど関係ありません。アプリ、ライブラリ、プロトコル、ファイル形式がどのように物事を処理するかという問題です。OSがテキストベースの設定またはコマンドラインコマンドを読み書きする場合を除き、OSをフォールトすることは意味がありません。
  2. ほとんどのWindowsアプリ両方\nを読むことができます\r\n\r\nみんなが幸せになるように出力します。プログラムは単に「やる」のどちらかしない\n\r\n-それは受け入れ 1、他の、またはその両方、および出力 1、他の、またはその両方を。
  3. これは実際にはほとんど必要がありますプログラマとして決してお邪魔しません。実際には、すべての言語/プラットフォームには、正しい最終行を記述し、最も堅牢に読み取る機能があります。私が問題に対処しなければならなかったのは、HTTPサーバーを作成したときだけでした-それは、特定のブラウザー(ヒント:IEの次に人気のあるブラウザー)が正しいの\n代わりにやっていたからです \r\n
  4. さらに適切な質問は、なぜ多くの最新のUnixアプリが、それを嫌う\nプロトコルやプログラムがあることを完全に知っているだけで出力するのかということです。

3
別の関連する質問:多くのプロトコルは主にUnixシステムで開発されたため、なぜ '\ n'を使用しないのですか?
デビッドソーンリー

@DavidThornley \ r \ nはクロスプラットフォームで動作する可能性が高いため(古いMacでは\ r、Windowsでは\ r \ n、* nixでは\ n)。
基本的な

4

さまざまなシステム(UNIXタイプシステムでは\ n、Windowsでは\ r \ nなど)で規則が保持される理由は、規則を選択すると、多くの人のファイルを壊さずに変更できないためです。そして、それは一般的に眉をひそめています。

Unixタイプのシステムは、テレタイプのさまざまなモデルを使用して(非常に初期の段階で)開発されました。

WindowsはDOSから来たので、Windowsの問題は本当に:DOSがこのcr / lfシーケンスを使用したのはなぜですか?私はそれがDOSにそのルーツのいくつかがあるCP / Mと関係があると推測しています。繰り返しますが、テレタイプの特定のモデルが役割を果たしている可能性があります。


面白いですね。
スフビル

1
で終わる行をWindowsが処理できない\nのに\r\n、今のところ使用し続けるのはなぜですか?Windows XPから開始した場合、ファイルの保存をの\n代わりに開始できるようになりました\r\n
DisgruntledGoat

1
Windowsはそれとは何の関係もありません。それはアプリの決定であり、ほとんどのアプリは「\ n」と「\ r \ n」の両方を読み取り、「\ r \ n」と書くので、誰もが幸せです。
宮坂

2

これが最高のソースであるマイクロソフトからの回答です。 ラインターミネータがCR + LFなのはなぜですか?

このプロトコルは、テレタイプライターの時代にまでさかのぼります。CRは「キャリッジリターン」の略です。CR制御文字は、紙を進めずにプリントヘッド(「キャリッジ」)を列0に戻しました。LFは「ラインフィード」の略です。LF制御文字は、プリントヘッドを動かさずに用紙を1行進めます。そのため、プリントヘッドを列0(次の行を印刷する準備ができている)に戻し、用紙を送りたい(新しい用紙に印刷する)には、CRとLFの両方が必要です。

RFC 0821(SMTP)、RFC 1939(POP)、RFC 2060(IMAP)、またはRFC 2616(HTTP)などのさまざまなインターネットプロトコルドキュメントにアクセスすると、CR + LFがすべてとして指定されていることがわかります。回線終了シーケンス。したがって、本当の質問は「なぜCP / M、MS-DOS、およびWin32は行末記号としてCR + LFを使用するのか?」ではありません。むしろ「なぜ他の人々はこれらの標準文書とは異なるものを選択し、他のラインターミネータを使用したのですか?」

Unixは、ライン終了シーケンスとしてプレーンLFを採用しました。sttyオプションを見ると、onlcrオプションがLFをCR + LFに変更するかどうかを指定していることがわかります。この設定が間違っていると、階段のテキストが表示されます。

each
    line
        begins

前の行が中断したところ。そのため、Unixをrawモードのままにしておくと、行を終了するためにCR + LFが必要になります。LFの前の暗黙のCRは、おそらく経済として、Unixの発明です。1行あたり1バイトを節約するからです。

C言語のUnixの祖先は、この規約をC言語標準に持ち込みました。これは、行を終了するために「\ n」(LFをエンコード)のみを必要とし、ランタイムライブラリに生ファイルデータを論理行に変換する負担をかけます。

C言語では、「一般的な行終端記号」の概念を表すために「改行」という用語も導入されました。ASCII委員会は1996年頃に文字0x0Aの名前を「改行」に変更したため、混乱レベルはさらに高くなったと言われています。

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