46

バックグラウンド:

Mac OS のバージョン 9 までのバージョンでは、テキスト ファイルの標準表現は、ASCII CR (キャリッジ リターン) 文字、値 10 進数 13 を使用して行の終わりを示していました。

Mac OS 10 は、以前のリリースとは異なり、UNIX に似ており、ASCII LF (改行) 文字、値 10 進数 10 を使用して行の終わりをマークします。

問題は、文字定数の値と、OS X より前の Mac OS リリースの C および C++ コンパイラの値は何'\n'ですか'\r'?

取ることができた可能性のある(少なくとも)2つの可能なアプローチがあります。

  1. ASCII LF 文字として扱い'\n'、テキスト ストリームへの出力およびテキスト ストリームからの入力で CR との間で変換します (Windows システムでの LF と CR-LF 間の変換と同様)。また
  2. '\n'入力または出力で変換を必要としない ASCII CR 文字として扱います。

2 番目のアプローチには、潜在的な問題がいくつかあります。'\n'1 つは、 LFであると想定するコードが失敗する可能性があることです。(このようなコードは本質的に移植性がありません。) もう 1 つは、 には別個の値が必要であり'\r'、ASCII ベースのシステムでは CR が唯一の適切な値であるということです。また、C 標準では許可されていないため'\n' == '\r'(5.2.2 段落 3 の引用を見つけてくれた mafso に感謝します)、他の値を に使用する必要があります'\r'

Nが 10 未満の場合、Mac OS Nでコンパイルして実行すると、この C プログラムの出力はどうなりますか?

#include <stdio.h>
int main(void) {
    printf("'\\n' = %d\n", '\n');
    printf("'\\r' = %d\n", '\r');
    if ('\n' == '\r') {
        printf("Hmm, this could be a problem\n");
    }
}

この質問は、C と C++ の両方に当てはまります。答えはどちらも同じだと思います。

答えは C コンパイラによっても異なる可能性がありますが、コンパイラの実装者が互いに一貫性を維持していることを願っています。

明確にするために、Mac OS の古いリリースがテキスト ファイルの行末を表すために使用していた表現を尋ねているわけではありません。私の質問は、定数の値と'\n'C'\r'または C++ ソース コードについてのみです。'\n'テキスト ストリームに出力すると (その値が何であれ)、システムの行末表現 (この場合は ASCII CR) に変換されることは承知しています。その動作は C 標準で必要です。

4

5 に答える 5

5

検索を行ったところ、特に次のような古い議論が記載されたこのページが見つかりました。

Metrowerks の MacOS 実装は、ファイルに関係する I/O での '\r' および '\n' エスケープに関して CR と LF の意味を逆にすることによって、さらに一歩進んでいますが、他のコンテキストではそうではありません。これは、テキスト モードで FILE または fstream を開くと、すべての '\r' が LF として出力され、すべての '\n' が CR として出力されることを意味します。同じことが入力 (エスケープ) にも当てはまります。 ASCII バイナリへの対応が逆になります。ただし、sprintf() を使用してバッファへ、または std::stringstream を使用して、メモリ内では逆になりません。これは紛らわしく、非標準ではないにしても、少なくとも他の実装よりも悪いと思います。

MSL には回避策があることがわかりました。ファイルをバイナリ モードで開くと、'\n' は常に == LF になり、'\r' は常に == CR になります。これは私が欲しかったものですが、この情報を入手する際に、これが私が欲しかったものを入手するための「標準的な」方法であるという多くの正当化もありました。実装。結局のところ、CR と LF は 7 ビットの ASCII 値であり、テキスト モードで開かれたファイルで標準的な方法でそれらを使用できると期待しています。

(答えは、これが実際に標準に違反していないことを明らかにします。)

したがって、明らかに、通常の ASCII 値を使用し、それらを (非バイナリ) ファイル出力に変換する実装が少なくとも 1 つはありました (それらを交換するだけで)。\n\r

于 2014-07-31T21:19:41.453 に答える
2

古い Mac コンパイラでは、\r と \n の役割が逆になっています。以前は '\n' == 13 と '\r' == 10 でしたが、現在は '\n' == 10 と '\r' == です。 13. 移行期がとても楽しい。古いコンパイラでファイルに '\n' を書き込み、新しいコンパイラでファイルを読み取り、'\r' を取得します (もちろん、どちらの場合も実際には 13 でした)。

于 2014-07-31T18:27:33.087 に答える
1

これに従っているかどうかを確認するための古い Mac コンパイラはありませんが、の数値'\n'は ASCII 改行文字と同じである必要があります (これらのコンパイラが実行エンコーディングとして ASCII 互換エンコーディングを使用したと仮定すると、それを行ったと私は信じています)。 )。'\r'ASCII キャリッジ リターンと同じ数値にする必要があります。

テキスト モード ファイルの書き込みを処理するライブラリまたは OS 関数は、数値を'\n'、OS が行を終了するために使用するものに変換する役割を果たします。実行時のこれらの文字の数値は、実行文字セットによって完全に決定されます。

したがって、ASCII 互換の実行エンコーディングであるため、数値は従来の Mac コンパイラと同じである必要があります。

于 2014-07-31T18:40:42.693 に答える