2

fputs() を使用して \n をファイルに書き込もうとすると、fputs() は \n を \r\n の組み合わせに変換し、fgets() を使用して同じ行を読み戻すと逆になるという本からこの概念を読みました。変換が発生するということは、\r\n を \n に逆変換することを意味します。この背後にある目的は何ですか?

4

2 に答える 2

3

端的に言えば、DOS がその理由です。

システムが異なれば、改行の規則も異なります。Unix では'\n'、行の終わりを示すには , という 1 文字で十分であると考えています。'\r'DOS は、との 2 文字が必要であると判断しましたが'\n'、他のシステムもその規則を使用していました。Mac OS 1 ~ 9 (Mac OS X より前) のバージョンは、'\r'代わりに使用されていました。他のシステムでは、行末の代わりにカウントと行データを使用したり、固定長 (72 または 80) までの空白でパンチ カードをシミュレートしたりできます。Unix では、バイナリ ファイルとテキスト ファイルも区別されません。DOSはそうです。(DOSControl-Zは、テキスト ファイルで EOF をマークするためにも使用します。Unix には EOF マーカーがありません。ファイルの大きさを正確に認識し、その長さを使用して、いつ EOF に達したかを判断します。)

C は Unix を起源としていますが、システム間でのコードの移行を容易にするために、標準 I/O パッケージは、テキスト ファイルで作業しているときに、入力側でネイティブの行末を単一の'\n'文字に変換して入力を統一することを定義しました。出力側は a'\n'をネイティブの行末に変換します。

ただし、テキスト ファイルについて言及するということは、これらのマッピングが発生しないバイナリ ファイルが必要であることも意味します。

ほとんどのインターネット プロトコル (HTTP など) では、行末マーカーにCRLF (キャリッジ リターン、ライン フィード、または'\r', ) が義務付けられていることに注意してください。'\n'

(実際には、MS-DOS や PC-DOS のように DOS のせいにするのは少し不公平です。DOS が存在する前に CRLF 行末規則を使用する他のシステムがあり、それらはインターネット上でより影響力があった可能性があります。しかし、ほとんどこれらの先祖代々のシステムはすべて実質的に廃止されており、Windows は、バイナリ ファイルとテキスト ファイルの区別が重要になり、CRLF 行末に遭遇する最近遭遇する環境です。)

C標準では、テキストファイルについて次のように述べていることに注意してください。

ISO/IEC 9899:2011 §7.21.2 ファイル

¶2 テキスト ストリームは、行に構成される文字の順序付けられたシーケンスであり、各行は 0 個以上の文字と終了改行文字で構成されます。最後の行に終了改行文字が必要かどうかは、処理系定義です。ホスト環境でテキストを表現するためのさまざまな規則に準拠するために、入力と出力で文字を追加、変更、または削除する必要がある場合があります。したがって、ストリーム内の文字と外部表現内の文字との間に 1 対 1 の対応がある必要はありません。テキスト ストリームから読み取られたデータは、次の場合にのみ、そのストリームに以前に書き出されたデータと必ず等しくなります。改行文字の直前にスペース文字がありません。最後の文字は改行文字です。読み込み時に改行文字の直前に書き出された空白文字が表示されるかどうかは実装定義です。

それは、起こるかもしれないし起こらないかもしれない多くのことです。特に、ファイルに書き込まれた末尾の空白は、標準に従って、入力に表示される場合と表示されない場合があることに注意してください。これにより、パンチ カード イメージまたは固定長レコードをサポートするシステムが規格に準拠できるようになります。

また、( Giacomo Degli Epostiが指摘したように) これはすべて、もともとテキスト ファイルとして書き込まれたファイルをバイナリ モードで開くと、 I から大幅に異なるバイトのリストが返される可能性があることを意味することに注意してください。 /O システム。改行ごとに 2 文字が表示されます。Control-Z256 バイトの倍数などである可能性がある「ブロック」境界まで、他の文字 (おそらく null バイト) が続くのが表示される場合があります。

于 2013-11-07T15:40:21.287 に答える