ファイルの最後の文字は何ですか?


18

「ファイルの最後にある改行文字を削除する」という答えを読んだところ、誰もが最後の文字を削除するように言われました。私の質問は、eofキャラクターは最後のキャラクターではないか?



1
@SorenBjornstadまた、Unixテキストファイルの最後に改行がある場合、最後の行を終了するため、改行があることも追加したいと思います。空のテキストファイルには末尾に改行がありません。ゼロ文字のシーケンスです。
カズ

3
CPMとDOSでは、少し面倒なことをするために、^ ZをEOF文字として使用しましたが、^ Zで終わるファイルに遭遇する場合があります。
エドワードフォーク

回答:


13

前の回答が正しく述べているように、ファイルはファイルの終わり文字で終了しません。しかし、答えとコメントには指摘する価値のある不正確さが含まれていると思います:

  • ASCII文字セットには正確なEOF文字が含まれていません。いくつかの「終了」制御文字があります:テキストの終わり(3)、伝送の終わり(4)、伝送の終わり(23)、媒体の終わり(25)。ファイル区切り(28)は、EOF文字に最も近い可能性があります。コード26はEOFではなく「代替」です。

  • Ctrl- D端末入力のみに関連付けられます。たとえば、コマンドに cat filea fileb filec > outfileCtrl- は含まれませんD。ちなみに、コマンドを使用してCtrl- 端末のEOF文字を- 以外のものに変更できます。Dstty

  • 厳密に言えば、Ctrl- D(または変更したもの)はEOFキーコードではありません。それがすることは、read使用可能な入力でシステムコールを返すことです。ちょうどリターンを押すと、読み取りシステムコールが呼び出し元に文字の行を返すようになります。慣例により、読み取りシステムコールからのゼロの戻り値(つまり、ゼロ文字の読み取り)は、ファイル終了条件を通知します。ただし、入力ファイルは自動的に閉じられません。また、入力が端末から来た場合、「ファイルの終わり」状態にはなりません。「ファイルの終わり」の後でも端末から読み取りを続けるプログラムを作成でき、読み取り呼び出しは次の入力行に対してゼロ以外を返すことができます。

  • eof文字とeol文字の類推は、入力がすでに行に書き込まれているときにCtrl- Dが押された場合に見ることができます。たとえば、「abc」と書いてCtrl- D読み取り呼び出しが戻ると、今回は戻り値3が返され、引数として渡されたバッファに「abc」が保存されます。readは0を返さないため、上記の規則ではEOF条件として解釈されません。同様に、returnキーを押すと、読み取り呼び出しが入力行全体(改行を含む)で戻ります。catコマンドでこれを試すことができます:行にいくつかの文字を書いてCtrl- を押しDます。文字がエコーバックされcat、さらに入力を待っているのがわかります。

  • 上記のすべては、行入力処理が最小化される「生」モードとは対照的に、端末が「調理済み」モードの場合にのみ適用されます。rawモードでは、Ctrl-D文字が実際に入力バッファーに配信されます。


19

ASCII制御文字には、1960年代の定義があります(実際には、ネットワークと見なされるものに先行します)。これらの制御文字のすべてが、当時の通信機器用に定義された方法で使用されるわけではありません。

Unixライクなシステムでは、EOFキャラクターは必要ありません。使用されません。システムは、ファイル内のバイト数をアプリケーションに通知できます。

  • 他の一部のシステム(VMS、DOS、Windowsで見られる)では、control-Zがファイルの終わりマーカーとして機能する場合があります。これは、古いバージョンでは、システムが一部のアプリケーションにファイルのバイト数を伝えることができなかったためです。

    VMSの場合、制限はCランタイムの動作方法によるものでした。アセンブリ言語アプリケーションは、正しいファイルサイズを取得できました(そして取得しました)。

  • シェル内のUnixシステムは従来、control-Dを使用して、入力(ファイル)の終わりに到達したことをアプリケーションに通知しますが、control-Dはファイルに保存されません。

Cでは、有効な文字ではないことを示すためにEOF意図的に作成さ-1れます。EOFファイルの終わり状態が検出されると、標準I / Oは戻ります。特殊文字ではありません。

ところで、ファイルは改行(ASCII 改行)文字で終わる必要はありません。テキストエディタは、すべて印刷可能なテキストであるが末尾の改行がないファイルに対処できます。


8
POSIXは、テキストファイルを一連の行を含むファイルとして定義し、各行は1行の改行が後に続く非改行文字のシーケンスとして定義されます。したがって、0x0A以外で終わるファイルは、適合テキストファイルではありません。
ダミアンジェリック16年

2
私はそれを承知しています。それが、テキストエディターが機能することを指摘した理由です。(バイナリファイルにはそのような制約はありません)。
トーマスディッキー

少なくとも実際にそれが必要な場合は、末尾の改行を持たないテキストとして処理することを意図したファイルは、間違いなく悪い形式です(そのようなファイルを補正するために典型的なテキストエディタがコーディングされている場合でも)広くユーザーフレンドリー末尾の改行の欠如は、(一般的なコマンドラインツール、などの最小限の編集者で解析し、連結/印刷複数のテキストファイルを、様々な状況で、追加の困難を追加することができますので、互換性/ busyboxさんvi、など)。
mtraceur

(1)VMSの前は、RT-11 RSX-11 TOPS-10にはブロックにのみ正確なファイルシステムがあり、EOF文字が必要でした。CP / Mも同様でしたが、CP / Mは明らかにDECからコピーし、初期のMS-DOSによってコピーされ、Windowsに渡されました。(2)Unixでは、JohanMが詳細に説明しているように、通常は ttyデバイスでシェルを実行しますが、シェルではなくttyドライバーです。
-dave_thompson_085

確かに-DECが戻ってきました(古いバージョンについても触れました)。CP / M機能の起源であるかどうかは、興味深いトピックです(ここではありません)。代替案の背景を説明するために、これらのケースに言及しました。
トーマス・ディッキー

7

EOFは文字ではありません。ファイルストリームから読み取る文字がこれ以上ないことを示す状態です。端末からEOFコマンドを入力すると、特殊文字を入力せずに、入力ストリームを閉じるようにOSに通知します。


1
はい。ただし、ASCIIテーブルではEOFは26であるため、最後のバイトは26のバイナリ表現だと考えました。入力を読み取るプログラムは、どのように終了するかを知ることができますか?
-sworwitz

ASCIIは、ネットワーク経由で情報を渡すためのものでした。その場合、EOF文字が必要です。(ASCIIにも多くの制御コードがありました。すべてが印刷可能であるわけではありませんでした。)ファイルストリームの場合、ファイルのサイズはファイルシステムを通じて既にわかっているため、読み取るデータがなくなったときにOSが認識できます。
ムニール

@sworwitz:Cに関して、呼び出しごとに文字を返す入力読み取り関数は、charではなくint(通常は32ビット数ですが、最小16ビットでなければなりません)を返します。この関数は、有効な8ビット値ではない-1(0xffffffff)を返すことでシグナルとEOFを通知するため、0xffでなくてもASCII文字と混同することはありません。文字列を返す関数は、読み込まれたデータの長さも返します。この長さは、データなしまたはデータの終わりを通知するために使用できます(ここでも、長さは-1にできます)。最後に、ストリームが最後に到達したかどうかを知らせる関数を呼び出すこともできます
-slebetman

よろしくお願いします!bashでCtrl + dを押すと、ASCII文字が入力されますよね?
-sworwitz

@sworwitz正確ではありません。bash入力に手を出す前に、TTYドライバーによってマッサージされます。このドライバーはCtrl-Dをインターセプトし、EOFを送信しますbash (EOFはキャラクターではなく、特殊なファイルステータスです)
スティグヘマー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.