改行コード

出典: フリー百科事典『ウィキペディア(Wikipedia)』

改行コード とは、ワードプロセッサ(ワープロ専用機)やコンピュータなどにおいて、改行を表す文字コードである。日本では「改行コード」と総称する事が一般的なため、本項目では、キャリッジリターン(CR)とラインフィード(LF)の両方について記載する。

目次

[編集] 概要

改行コード(広義)は以下の2種類であり、システム(ソフトウェア)により片方または両方が使用される。

  • キャリッジリターン(英:Carriage returnCR、復帰)
  • ラインフィード(英:Line Feed、LF狭義の改行)またはニューライン(英:newline、line break or end-of-line、EOL

これらの用語はタイプライターが由来である。タイプライターでは印字装置は固定され、紙の方が上下左右に移動することで、文字送りや行送りが行われる。英語などの左横書きにおける「キャリッジリターン」とは、紙を固定して移動する装置(キャリッジ)を元の位置に戻す(リターン、つまり紙の左端に印字装置が来る)ことである。「ラインフィード」とは紙を必要な行(ライン)だけ上に送る(フィード、つまり下の行に印字装置が来る)ことである。

コンピュータでは、同じ文字コード(例:ASCII)を使用していても、改行コードは異なる場合があるため、異なるシステム間でのデータのやりとりには注意する必要がある。

[編集] 改行の数値表現

多くのシステムでは、改行コードを1つか2つの特殊文字の連続で表している。

IBMメインフレームシステムでは主にNEL(Next Line、0x15)を改行コードとして使う。EBCDICはCRLFと呼ばれる制御文字も持つが、これらはASCIIにおけるCRLFとは値が異なる。また、NELに対して異なる値を割り当てたEBCDICの亜種も存在する。なお固定長のデータセットでは、通常は改行コード自体が不要なため使用されない。
  • OpenVMSはレコードベースのファイルシステムを使用しており、テキストファイルの各行を1レコードとして保存する。保存する際は改行コードは記録されないが、アプリケーションから読み込まれる際に自動的に行終端記号を付加する機能がある。

テキストによって情報をやりとりするインターネットプロトコルの多く(HTTPSMTPFTPIRCなど)はプロトコルレベルでCR+LFコードを用いるよう要求しているが、アプリケーションはLFコードにも対応することが推奨されている。これは初期のインターネットサーバの多くがDEC機によって構成されていた名残である。

[編集] 歴史

テレックスに用いられていたITA2では、「改行」の動作をCR(0x08)+LF(0x02)によって実現していた。すなわち、プリンタヘッドを新しい行の先頭に移動するという「改行」の動作を、現在行の先頭に移動するCR(キャリッジリターン→横移動)の動作と、新しい行に移動するLF(ラインフィード→縦移動)という2つの動作に分割し、それぞれ独立して制御するよう設計されていた。そのため、例えば行の途中でLFを伴わない単独のCRを送り、そのまま通常文字を出力することで、先に出力した文字に重ね書きすることが可能であったし、CRを伴わない単独のLFを用いて新しい行の途中から文字を出力することも可能であった。

ASCIIコードは、ISOASAANSIの前身)によって並行して開発されていた。1963年~1968年、ISOの草案はCR+LFLFの両方を改行コードとしてサポートしていたが、ASAの草案ではCR+LFのみがサポートされていた。1964年から開発が開始されたMulticsオペレーティングシステムはLFを改行コードとして採用し、UNIXやUNIXに続くシステムもそれにならってLFを採用した。

当時のシステムでは、テキストはテレタイプ端末との互換性を考慮して構成される必要があった。アプリケーションからハードウェアの詳細を隠蔽するデバイスドライバという概念がまだ発展していなかったため、アプリケーションはテレタイプ端末と直接やりとりをし、テレタイプ端末の慣習に従う必要があったのだ。このシステムでは、プリンタヘッドが右端から復帰するのに1文字の時間では間に合わなかった。これがCRが先に送られた理由である。実際には、プリンタヘッドが停止するのを待つためにCR+LF+NUL(最後に「何もしない」という命令を送る)やCR+CR+LFCRを二度送る)というシーケンスを送る必要があることもあった。このようなシステムが消滅してからはCR+LFのような2文字の改行コードは技術的な意味を持たないが、現在も一部のシステムで存続している。

QDOSマイクロソフトが買収し、MS-DOSと改名した)がCR+LFを採用したのは、CP/Mの実装を真似たためだと考えられている。更に、CP/MがCR+LFを採用した理由はいくつかの説が考えられている。一つは、CP/MはUNIXをモデルとしていたため、UNIXの著作権を侵害したとしてAT&T/ベル研究所から訴えられる可能性を軽減しようとしたという説だ。もう一つは、CP/MはRT-11のようなDECオペレーティングシステムをモデルとしており、DECはもともとテレタイプ端末としての使用を想定して設計されていたという説だ。

その原因が何であれ、この慣習は後のMicrosoft Windowsに継承されている。

[編集] プログラミングにおける改行コード

ポータブルなプログラムを記述するために、プログラミング言語は異なる改行コードを扱うためにある程度の抽象性を提供している。

C言語'\n'(改行)、'\r'(復帰)の二つのエスケープシーケンスを提供している。しかし一般的な認識に反して、これらのエスケープシーケンスは一般的にはLFCRと等価ではない。C言語は次の二つの事柄のみを保証している。

  1. これらのエスケープシーケンスはそれぞれ異なった環境依存のchar型に収まる範囲の数字に変換される。
  2. テキストモードでファイルに書き込むとき、'\n'はシステムで使用されている改行コードに変換される。この改行コードは1文字に収まるとは限らない。逆にテキストモードで読み込む時、改行コードのシーケンスは'\n'に変換される。バイナリモードにおいてはいかなる変換も行われない。

C言語の母体であるUNIXでは、改行シーケンスはLFであり、'\n'は単純にその値として定義されている。内部表現と外部表現が一致しているので、変換は行われない。従ってテキストモードとバイナリモードは同じように振舞う。このためUNIXで開発をするプログラマはこれらの区別を無視することができ、結果として互換性を欠いたコードを書いてしまうことがある。

もう一つの問題として、CR+LFの使用を要求するインターネットプロトコルを使ってテキストをやりとりする場合がある。そのようなストリームに対し'\n'を送るという方法はWindowsシステムにおいては正しく動作するが、UNIXにおいてはLFしか送信されないため、問題となる。これに対し、バイナリモードで'\r\n'を送るという方法は多くのASCII互換システムにおいて正しく動作する。しかし、必ずしも一般的に成功するとは限らない。一つの解決策として、バイナリモードを使って目的の数値(\x0D\x0A)を直接送るとどのような場合も正しく動作する。

Java'\n''\r'といったエスケープシーケンスをサポートする。C言語と異なり、それぞれ0x0A0x0Dを表すものであると保証されている。Javaの入出力ライブラリがこれらの文字を環境依存の改行コードに変換してくれる。たとえば System.out.print("\n"); はEBCDIC(Cp1047)環境では 0x15 が出力される。また、CRLFCR+LFのいずれをも改行コードとみなして行を読み込む関数を提供している(BufferedReader.readLine())。

[編集] 関連項目

[編集] 外部リンク