おもこん

おもこんは「思いつくままにコンピュターの話し」の省略形です

改行コード

改行コードについて

少し前に文字コードについて書きましたが、改行コードについても気をつけなければいけない点があります。簡易掲示板のスクリプトでも、改行コードにを神経を使っています。

改行コードの歴史

現在はPCからユーザへの出力はディスプレイを使いますが、初期のコンピュータではテレタイプが使われていました。タイプライターが電動になり、PCに繋がっているようなものだと考えて良いと思います。タイプライターの場合、改行は2つの操作に分解されます。
CR(キャリッジ・リターン)  印字位置を用紙の左端に持ってくる(※注)
LF(ライン・フィード)    紙を1行分送る
(※注)手動タイプライターの場合、1字打つ毎に、紙をセットしたローラ(キャリッジ)が動いていく。その行を打ち終わったら、ローラが逆方向に動き印字位置が紙の左端にくるようにリセットされる。ローラ(キャリッジ)が元に返る(リターン)、すなわちキャリッジ・リターンである。テレタイプや電動タイプライターでは、活字がアームではなく、円筒形やボールになっていて、活字の方が横に動いていた。従ってローラ(キャリッジ)は横には動かなかったが、印字位置のリセットは、キャリッジ・リターンと呼ばれた。(注:この説明は検証が十分ではありませんので、引用は避けてください)

このことから、元々改行はCR+LFであったことが分かります。これがディスプレイの時代になっても引き継がれたのがWindowsで用いられている改行コードの体系です。それに対して、1つのコードで改行を表した方が節約になりますから、CRだけで改行を表す(Macintosh)、LFだけで改行を表す(Unix)方法も現れました。

改行と文字コード

HTTPプロトコルでは、エンティティは別として、ASCIIコードを使うことになっています。ASCIIは7ビットのコード体系で古くから使われています。ASCIIでは、CRを十六進数の0D(これを\x0Dと書くことにします)、これを十進数で表すと13、LFを\x0A(十進数の10)と定めています。UTF-8、EUC-JP、Shift_JISなどのコード体系もASCIIとの互換性を考えられているので、CR, LFのコードは同じく\x0D, \x0Aです。

先ほど述べたように、PCで使われる主なOSでは、改行コードは
Windows, MS-DOS     CR + LF \x0D0A
Macintosh           CR      \x0D
Unix, Linux         LF      \0A
となっています。HTTPプロトコルでは、改行を CRLF(\x0D0A) と定めています。異なるシステム同士で通信する場合は、プロトコル(通信手続き)を厳密に定めておかないといけませんが、改行コードも同じです。プロトコルには改行コードをどうするかも含まれているはずです。

NL とは

NL(New Line 新しい行)とは、改行のことです。プログラミング言語の中では、改行を表すときNLと書くことが多いです。文字コードも改行コードもシステムの問題ですから、本質的にはプログラミング言語には関係ありません。ですから、どういう文字コード、改行コードのシステムであろうとプログラミング言語を移植して動かすことは可能です。そして、言語上NLとしているものが、あるシステムではCRLFになり、別のシステムではLFになれば良いのです。その部分は言語自身は知らなくても良い、実装の問題だということです。perlでは改行を \n と書きます。
"Hello world ! \n"
この \n が NL です。この NL がどういうコードになるかは、実装による(と思います)。Linuxでは\x0Aになっていました。
$value =~ s/\x0D\x0A|\x0D|\x0A/\n/g;
これは、簡易掲示板で改行コードをperlの改行に置換しているところですが、置換後のコードを \n として、0x0A にしなかったのは、サーバのシステムによらない汎用性を考えてのことです。

ウェブ・アプリでは細かいところも見逃さずに

自分の使っているPCでアプリを作るときは、改行コードなどは定まっていますから、気にしなくても問題ありませんが、ウェブ・アプリの場合は受け取ったデータがどういう文字コード、改行コードなのかなど、データ形式を正しく把握しないとバグに繋がりますから、細かいところも見逃さないようにしましょう。