改行コード

出典: フリー百科事典『ウィキペディア(Wikipedia)』
移動: 案内検索

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

概要[編集]

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

  • キャリッジリターン: carriage returnCR、復帰)
  • ラインフィード(: line feedLF狭義の改行)またはニューライン(newline、line break または end-of-lineEOL

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

コンピュータでは、同じ文字コード(例: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はもともとテレタイプ端末としての使用を想定して設計されていたという説だ。

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

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

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

C言語では'\n'(改行)、'\r'(復帰)の二つのエスケープシーケンスを提供している。言語処理系はこれらのエスケープシーケンスをそれぞれ異なった環境依存のchar型に収まる範囲の数字(例えばUNIXやWindows上の一般的な処理系においては、それぞれ、0x0A0x0D)に変換する。

ただし、よく使われる出力関数のprintfputs、入力関数のfgetsなどでは、'\n'に相当する数値(上記の例では0x0A)は特殊な値として処理される。これらの出力関数ではテキストモードで開かれたファイルにデータを出力する時、'\n'の部分がシステムで使用されている改行コード列に変換された文字列がファイルに出力される。例えば、UNIXでは、改行コード列は「0x0A」であり、Windowsでは「0x0D 0x0A」、Macintoshでは「0x0D」である。また、入力関数fgetsはテキストモードで開かれたファイルからデータを読み込む場合、ファイル中にシステム依存の改行コード列があれば、その部分を'\n'に対応する数値に変換したものを変数に格納する。ファイルがバイナリモードで開かれている場合には、どの入出力関数も数値を変換をせずそのままの値として読み書きする。

これらの関数は、「0x0D 0x0A」の使用を要求する通信プロトコルを使ってテキストをやりとりする場合に問題になる。そのようなストリームに対し、printf関数などを使い'\n'を出力すると、Windowsシステムにおいては期待通り「0x0D 0x0A」が送信されるが、UNIXにおいては「0x0A」しか送信されないため、問題となる。解決策として、バイナリモードを使って目的の数値(0x0D 0x0A)を直接送るとどのような場合も正しく動作する。

Java言語でも'\n'(改行)、'\r'(復帰)の二つのエスケープシーケンスを提供している。言語処理系はこれらのエスケープシーケンスを、それぞれ、16ビットの数値0x000A0x000Dに変換する。(Java言語の char型 は16ビットUTF-16である。)

よく使われるjava.io.PrintStreamクラスのprintメソッドやprintlnメソッド、printfメソッドは、C言語の printf 関数とは異なり、これらの数値を特別扱いせず、環境依存の改行コードに変換しない。ただし、printfメソッドで使われる書式文字列中では「改行」を表現するための特殊な表記として「%n」を使える。printfメソッドはこの部分を実行環境依存の改行コードに置換した文字列を出力する。また、いずれのメソッドでも、出力されるバイト数、バイト順については設定された文字符号化方式に依存する。

関連項目[編集]

外部リンク[編集]