新・闘わないプログラマ No.431

改行する


改行文字というのがあります。「いきなり何を言い出すんだ」とお思いかも知れませんが、要するにあれです、コンピュータが扱うテキスト上で、改行を示す特殊文字(制御文字)です。「文字」とは言いつつ文字として表現できるものではなく、画面にその改行文字を出力すると次の行の先頭に移る、というものです。
……なんて「コンピュータ用語辞典」みたいな話を長々としていても仕方ありませんので止めておきますが、この改行文字は、OSによってさまざまなものが用いられているのはご承知のとおりです。よく知られているように、

といった具合です。……とここまで書いて「あれ?」と思いました。昔のMac OSは改行文字がCRだったのは間違いないのですが、いまのMac OS Xはどうなんでしょう? あれってベースはUNIXですし。
というわけで調べてみました。Mac OS 9とMac OS Xの標準(であろうと思われる)テキストエディタ、SimpleTextとTextEditでテキストファイルを作成してみたところ、

という結果になりました。どうやらMac OS Xでは、LFが標準の改行文字のようです。もうちょっと調べてみるために、WindowsとMac OS Xの間で、FTPのASCIIモードでファイルの転送をしてみました。

この結果から、やっぱりMac OS Xの改行文字はLFが標準みたいです。これは、Mac OS XをUNIXとみなせばごく当たり前の結果ですし、「そうしておかないと、いろいろと問題が起こるだろうなあ」ということは想像できます。たとえばUNIXで必要となる各種の設定ファイルの改行文字をすべてCRにしようとしたら、恐ろしく大変なことになりそう(その上、そんなことしても実りは少なそう)ですし。
しかし、Mac OS Xの標準的な改行文字がLFだったのは「Mac OSの改行文字はCR」というのがずっと頭にあった私としては、ちょっと意外でした。そういえば、どれかの本に「Mac OSの場合、改行文字はCRになります」って何も考えずに書いちゃったような気がするけど……ううむ、どうしましょ。

さて、改行文字がOSによって異なる、というのは、あちこちでいろいろと問題を引き起こします。いま改行文字のテストのために使ったFTPには、ASCIIモードというのがあって、このモードを使うと、には改行文字をそのOSに合ったものに自動的に変換してくれます。ただ、テキストじゃないファイルに対して、このASCIIモードで転送を行うと、ファイルの内容が壊れてしまう可能性があります。
また、Windowsの場合、改行文字はCRとLFの2バイトで表現されます。これは、プログラマにとっては厄介です。たとえば、Cのプログラムで、

    putchar('\n');      /* \は本当はバックスラッシュ */

と書いた場合、Windowsでは「CR LF」(0x0d0a)の2バイトが出力されます。ここで、'\n'は、プログラムの中での改行文字を表していて、これのサイズは1バイトです。つまりプログラム内では1バイトを出力したはずなのに、OSによっては、現実には2バイト出力されることもありうるわけです。こういうことは他にもあるので、この改行文字だけに目くじらをたてても仕方ないといえば仕方ないのですが、とは言え、なんか気持ちが悪いのも事実です。
そもそも、なんでOSごとに改行文字が異なっているのでしょうか。それ以前に、CRとかLFとかいうのはいったいどういう文字(制御文字)なのでしょうか。
CRは、キャリッジリターン(Carriage Return)の略です。「キャリッジ」というのは、タイプライターの用紙を押えておく、左右に動く部分のことです。タイプライターは、一文字打たれるごとに紙が左に一文字分ずれていくようになっています。活字側のほうが動かなくて、紙が横方向に動くことによって順番に文字を印字するわけですね。で、「キャリッジリターン」というのは、そのキャリッジ、つまり「タイプライターの用紙を押えておく部分」を元に戻す動作のことです。いまどきタイプライターを使う人はほとんどいないと思いますが、昔の外国映画なんかで、秘書のおねーさん(じゃなくてもいいですが)がタイプライターを使っていて、このキャリッジを手で戻す操作をしているのを見たことがあるかと思います。
なお、コンピュータのプリンタの場合は逆で、たいていは印字ヘッドのほうが左右に動いて順番に印字して、紙を左右に動かすことはしません。これは昔からそうです。プリンタの場合は、昔は連続用紙を使っていた関係上、紙のほうを左右に動かすことができなかったのでしょう。
一方、LFはラインフィード(Line Feed)の略です。キャリッジを戻すと、また行頭から印字できるようになるわけですが、キャリッジを戻しただけだと、同じ行に二重打ちしてしまいます。そこで紙を一行分送る必要があります。この動作がラインフィードです。タイプライターの場合、普通にキャリッジを戻すと一行送られます(送らないで、二重打ちすることもできる)ので、わざわざこの操作をする必要はないのですが、コンピュータの制御文字としては、行頭に戻す(CR)と、一行送る(LF)を分けています。

こう考えてみると、Windowsの改行文字「CR LF」が一番理に適っているようにも思えてきます。ネットワークの世界でも、多くのプロトコルで「CR LF」が改行文字として採用されています。ただ、そういうデータを扱うプログラマ側の立場からすると、「2バイトで改行を表す」というのは面倒なわけで、できれば、そういうのはやめて欲しいなあ、とも思うわけです。いまさらタイプライターを念頭に置かなくても、と。
たとえば、Windowsでテキストファイルを読む場合、改行文字はもちろん「CR LF」なわけですが、もし、読んでいたファイルに「CR」の次に「LF」の無いデータあったらどうするのか、とか、「LF」の前に「CR」の無いデータがあったらどうするのか、とか、「LF CR」と入っていたらどうするのか、とか、そんなところで悩みたくないわけです。
で、なんで今回こんなテーマを取り上げたかというと、LFしか入っていないファイルを、あるWindows上のシステムで読ませたら、えらいトラブル(詳細は差し障りがあるので秘密)が起こってしまった、ということがあったばかりだったわけで、なんでLFしか入っていなかったかと言えば、UNIX側で作ったファイルをそのまま(改行文字の変換を行わないで)持ってきて読ませたからだったりするわけで……でも、その程度のことで、あんなトラブル(詳細は差し障りがあるので秘密)になるような作りもどうかしているわけで……ぶつぶつぶつぶつ。

[前へ] [次へ]

[Home] [戻る]


mailto:lepton@amy.hi-ho.ne.jp