質問: これら改行がプログラム上どのように処理されるのかが知りたいです。 タイトルの通りなのですが、調べてもいまいち腹に落ちる解が得られなかったので知識を頂戴させてください。 現状、各改行コードは以下の処理をしてる認識です。 CR : MacOS 左端に寄せ (CR) 自動で改行 LF : UNIX系 改行 自動で左寄せ 改行している (LF) CRLF : Windows 左寄せ (CR) 改行 (LF)
回答: 改行コードの歴史や概要はWikipedia:改行コードによくまとまっていますので、まずはこちらを確認してみてください。 さて、上を踏まえて、プログラムではどのように処理されるのかを解説したいと思います。 ※ 以下の文章で、UNIX/LinuxにはMac OS X(最新版はmacOSと名称変更)が含まれます。Mac OS XはUNIXの一つです。 ### プログラムでの動作 #### テキストモードとバイナリモード C言語由来かC言語に影響を受けた言語の多くでは、ファイルを開くときに、テキストモードとバイナリモードという区別があります。それぞれのモードおよびOSの組み合わせで、ファイルの入出力時に改行コードの変換を行う場合があります。(標準入出力もファイル入出力の一つであり、デフォルトではテキストモードとして処理されます) | OS | テキスト入力 | テキスト出力 | バイナリ入力 | バイナリ出力 | | --- | --- | --- | --- | --- | | Windows | `CRLF`->`LF` | `LF`->`CRLF` | (何もしない) | (何もしない) | | UNIX/Linux | (何もしない) | (何もしない) | (何もしない) | (何もしない) | つまり、**プログラム内部では常に改行を`LF`として扱い、入出力するときに自動変換される仕組み**です。これはFTPのASCIIモードやgitのcore.autocrlfが有効な場合等も同じ動作をします。ただし、この動作は**Windowsのみ**です。UNIX/Linuxではテキストモードとバイナリモードの区別は無く、どちらも同じ動作をします。 #### テキストストリームとバイナリストリーム JavaやC#ではテキストモード・バイナリモードという考えてでは無く、テキストストリーム・バイナリストリームという考えで処理します。テキストストリームとして処理する場合、 * 読み込み時は、`CR`、`LF`、`CRLF`のどれかであれば改行の区切りとして扱い、行単位で処理する。1行を取得したとき、**末尾に改行コードは含まれない**。(なので、改行コードがどれであっても同じ処理になる) * 書き込み時は、改行のみまたは最後に改行するメソッドを用い、システム規定の改行コードを出力する。 という動作になります。出力に関してはOSによって改行コードの規定値が異なることがありますが、入力はOSによって変わるということはありません。また、出力時の改行コードは変更することができます。 ### その他 #### 旧Macの`CR`のみについて Mac OS 9(以下、旧Mac)では、テキストにおける改行は`CR`でした。Mac OS XからはUNIX化下のに伴い、UNIX/Linuxと同じく`LF`のみになっています。旧Macは既にサポートもされておらず、動作するのは骨董品のMacのみです。旧Mac時代に作られたテキストファイルでなければ、改行が`CR`のみの処理について気にする必要はありません。 #### `CR`のみの場合のCUIでの動作 WindowsのコマンドプロンプトやUNIX/Linuxでのターミナルでは、`CR`はまさしく`CR`として動作します。どういうことかというと、`CR`が入力されると、カーソルが行の先頭に戻ります。これを利用すると、CUIでもプログレスバーを表示するなどができます。 なお、Windowsのコマンドプロンプトで`LF`のみを渡しても、普通に改行され、カーソル位置は先頭になります。 #### 通信プロトコルについて 多くの通信プロトコル(SMTPやHTTP等)では、改行コードを`CRLF`としています。OS毎の動作が変わらないように、ネットワーク通信はバイナリのストリームとして扱い、プロトコルの仕様に従って改行コードを処理する必要があります。しかし、正しい改行コードを使っていない実装もありますので、実際はどのような改行コードであっても処理できるようにすべきでしょう。 ### telnetやSSH通信 通常、Enterキーを押したときに、クライアントからサーバへは`CR`のみが送られます。これは、押されたキーを送るのであって、改行コードを送っているというわけでは無いからです。つまり、本来のターミナルやコンソールでキーボードのEnterキーを押されたときに`CR`が送られると同じ動作をしているというわけで、`CR`のみであっても仮想ターミナル(pty)側で正しく改行してくれます。