web-dev-qa-db-ja.com

本当にEOFバイナリファイルの場合?条件?文字?

これまで、EOFはテキストファイルの末尾に自動的に挿入されてその末尾を示す特殊文字であることを知っていました。しかし、私は今、これについてもう少し明確にする必要があると感じています。私はGoogleとWikipediaのページでEOFを確認しましたが、次の質問には答えられず、このための正確なスタックオーバーフローリンクもありません。だからこれで私を助けてください:

  • 私の本では、バイナリモードのファイルは、ファイルのディレクトリエントリに存在する文字数からファイルの終わりを追跡していると述べています。 (特別なEOF文字で終了をマークするテキストファイルとは対照的です)バイナリファイルのコンテキストでのEOFのストーリーは何ですか?次のプログラムは、バイナリモードで!=EOFファイルからの読み取り中に.exe比較を正常に使用します。

     #include<stdio.h>
     #include<stdlib.h>
    
     int main()
     {
    
      int ch;   
      FILE *fp1,*fp2;
    
      fp1=fopen("source.exe","rb");
      fp2=fopen("dest.exe","wb");
    
      if(fp1==NULL||fp2==NULL)
      {
      printf("Error opening files");
      exit(-1);
      }
    
      while((ch=getc(fp1))!=EOF)
      putc(ch,fp2);
    
      fclose(fp1);
      fclose(fp2);
    
      }
    
  • EOFは特別な「キャラクター」ですか?それとも条件は、ウィキペディアが言うように、コンピュータが-1(私のコンピュータではEOF)のような特定の値をいつ返すかを知っている条件ですか?そのような「条件」の例は、文字読み取り関数が存在するすべての文字の読み取りを終了したとき、または文字/文字列I/O関数が読み取り/書き込み中にエラーに遭遇したときです。

    興味深いことに、EOFのスタックオーバーフロータグは、EOFの両方の定義をブレンドしました。 EOFのタグは言った "プログラミングレルムでは、EOFはバイト(またはchacracter)のシーケンスであり、これ以降の内容。 "、" about "セクションで"ファイルの終わり(一般にEOFと略される)は、データソースからこれ以上データを読み取ることができないコンピューターオペレーティングシステム。データソースは通常、ファイルまたはストリームと呼ばれます。 "

しかし、I/O中にエラーが発生した場合、他のすべての関数がそれを返すように見えるので、EOFは文字にはなりません。

あなたが私のために問題を解決することができれば、それはあなたの本当に素晴らしいことです。

21
Thokchom

Cが提供するさまざまなEOFインジケーターは、ファイルシステムがファイルの終わりをマークする方法とは必ずしも関係ありません。

最近のほとんどのファイルシステムでは、ファイルの内容とは別に、どこかに記録するため、ファイルの長さがわかります。ファイルを読み取るルーチンは、どこを読み取っているかを追跡し、最後に到達すると停止します。 Cライブラリルーチンは、EOF値を生成してユーザーに返します。実際にはファイル内にある値を返していません。

Cライブラリルーチンによって返されるEOFは実際には文字ではないことに注意してください。Cライブラリルーチンは通常intを返し、intどちらか文字値またはEOF。たとえば、1つの実装では、文字には0〜255の値があり、EOFには値-1がある場合があります。ライブラリルーチンがは、ファイルの終わりに遭遇しましたが、実際には-1の文字はありませんでした。あなたへ。

古いファイルシステムとファイルシステムには、ファイルの終わりを示す値が含まれている場合があります。さまざまな理由から、これは通常望ましくありません。最も単純な実装では、ファイルの終わりマーカーをデータとして保存できないため、ファイルに任意のデータを保存することができません。ただし、ファイル内の生データにファイルの終わりを示す何かが含まれている実装も可能ですが、読み取りまたは書き込み時にデータが変換されるため、任意のデータを格納できます。 (たとえば、ファイルの終わりマーカーを「引用」することによって)。

場合によっては、ファイルの終わりマーカーなどもストリームに表示されます。これは、端末(または疑似端末または端末のようなデバイス)から読み取る場合に一般的です。 Windowsでは、control-Zを押すと、ユーザーが入力を完了したことを示し、ファイルの終わりに到達する場合と同様に処理されます。これは、control-ZがEOFであることを意味しません。端末から読み取るソフトウェアは、control-Zを認識し、それをファイルの終わりとして扱い、ファイルの終わりを示す情報を返します。これは、control-Zとは異なる可能性があります。 Unixでは、control-Dは通常、入力の終わりを示す同様の歩哨です。

27

これで問題が解決するはずです。

基本的に、EOFは、I/O関数からのエラーコードを表す定義済みの値を持つ単なるマクロであり、読み取るデータがなくなったことを示します。

2

ファイルには実際にはEOFが含まれていません。 EOFは一種の文字ではありません。1バイトは0から255の間である可能性があるので、ファイルに-1が含まれている場合は意味がありません。EOFは、使用しているオペレーティングシステムからの信号で、ファイルの終わりに達したことを示します。getc()がintを返す方法に注意してください。 -1は、ストリームがファイルの終わりに達したことを示します。

EOF信号はバイナリファイルとテキストファイルで同じように扱われます-バイナリとテキストストリームの実際の定義はOSによって異なります(たとえば、* nixバイナリとテキストモードは同じです)。どちらにしても、前述のとおり、ファイル自体の一部ではなく、OSはそれをgetc()に渡して、ストリームの終わりに達したことをプログラムに通知します。

から GNU Cライブラリ: から

このマクロは整数値であり、ファイルの終わりの状態、またはその他のエラー状況を示すために、多数のナローストリーム関数によって返されます。 GNU Cライブラリの場合、EOFは-1です。他のライブラリでは、その値は他の負の数になる場合があります。

1
user2395375

EOFは文字ではありません。この文脈では、それは-1であり、技術的には文字ではありません(非常に正確にしたい場合は、文字である可能性があると主張できますが、この説明では関係ありません)。 EOF、明確に言えば、「ファイルの終わり」です。ファイルの読み取り中は、いつ停止するかを知る必要があります。そうしないと、環境によっては、ファイルの最後にpastを読み取ろうとすると、多くのことが発生する可能性があります。

したがって、マクロは、EOFというファイルの読み取り中にファイルの終わりに達したことを通知するために考案されました。 getcの場合、これはintではなくcharを返すため機能します。したがって、char以外のものを返す余地があり、EOF。他のI/O呼び出しは、例外をスローするなど、EOFに異なるシグナルを送る場合があります。

興味深い点として、DOSでは(そしておそらくWindowsでも?)実際の物理的な文字^Zは、ファイルの終わりを示すためにファイルの終わりに配置されました。したがって、DOSでは実際にはEOF文字がありました。 Unixにはそのようなことはありませんでした。

0
Eric