web-dev-qa-db-ja.com

'\ n'と '\ r \ n'の違い

はいはい、私は'\n'はUNIXで改行を書き込みますが、Windowsの場合、2つの文字シーケンスがあります:'\r\n'。これはすべて理論的には非常にいいですが、私の質問はwhy?です。 Windowsでキャリッジリターン文字が余分にあるのはなぜですか? UNIXが\nこれを行うのにWindowsが2文字かかるのはなぜですか?

私はDavid BeazleyのPython本を読んでいて、彼はこう言っています:

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

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

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

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

108
sukhbir

下位互換性。

WindowsはMS-DOSと下位互換性があり(積極的にそう)、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 。用紙が最初に上に移動し、次にキャリッジが戻ってきたことに注意してください。丁は終わりが近づいたことをタイピストに通知し、それに備えました。

133
user1249

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

\rはキャリッジリターンです。これは、ページで入力している場所を左(またはカルチャの場合は右)に移動するものです。

\nは新しい行で、紙を1行上に移動します。

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

コンピューターが登場したとき、古いモデルを維持している人もいましたが、それが必要ではないことに気づき、改行全体を1つの文字としてカプセル化した人もいました。

21
Matt Ellen

これが常識であるかどうかはわかりませんが、CRは現在のターミナルエミュレータでまだ理解されていることに注意してください。

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

進行状況インジケーターなどに便利です。

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

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

復帰とは、「入力したビットを行の先頭に戻す」ことを意味します。

MS-DOSが、CP/Mが、シリアル回線に意味があるため、WindowsはCR + LFを使用します。

マルチはそうしたので、Unixは\ n規約をコピーしました。

深く掘り下げると、実装者間の政治的不一致が見つかるのではないかと思います。

(あなたは余分な楽しい部分を省きました、Macの慣習はCRを使って行を分離することです(または以前はそうでした)。そして今ではUnicodeにも独自の行セパレーターU + 2028があります!)

7
Frank Shearar

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

ASCIIは、ISOとASA、ANSIの前身である組織によって同時に開発されました。 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に従いました。

6
Craige

「なぜUnixはWindowsではなく\nを実行できるのか」と尋ねる人々とは何ですか?奇妙な質問です。

  1. OSはそれとほとんど関係ありません。これは、アプリ、ライブラリ、プロトコル、ファイル形式がどのように処理するかという問題です。 OSがテキストベースの設定やコマンドラインコマンドを読み書きする場合を除いて、OSに障害が発生しても意味がありません。
  2. ほとんどのWindowsアプリcan\n\r\nの両方を正常に読み取ります。また、\r\nを出力して、みんなが幸せになるようにします。プログラムは、単に\nまたは\r\nのいずれかを「実行」するだけではありませんaccepts one、other、or both、and outputs one、other、or both。
  3. プログラマーとしては、これは本当にほとんどnever気になるはずです。事実上、すべての言語/プラットフォームには、正しい最終行を記述し、最も確実に読み取る機能があります。私が問題に対処しなければならなかった唯一の時間は、私が HTTP server -を書いたときであり、それは特定のブラウザ(ヒント:IEの次に人気のあるブラウザ)が代わりに\nを実行していたためでした 正しい\r\n
  4. もっと適切な質問は、なぜそんなに多くの最近のUnixアプリは、それが気に入らないプロトコルやプログラムがあることを完全に知っている\nだけを出力するのでしょうか?
5
Rei Miyasaka

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

Unixタイプのシステムは、さまざまなテレタイプのモデルを使用して(ごく初期に)開発され、ある時点で、ラインフィードを行ったときに装置が改行する必要があると誰かが決定しました。

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

4
Michael Kohne

これが最高の情報源-Microsoftからの回答です。 ラインターミネータが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は、1行あたり1バイトを節約するため、おそらく経済的なものとして、UNIXの発明です。

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

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

2
Ondra Žižka