• ベストアンサー

EOFについて

C言語学習中です。基本と思いますが、お分かりの方教えて下さい。 ファイルの終了記号「EOF(=-1)」っていつ誰が書くのでしょうか。 (書き込み後、fcloseする時でしょうか。) 例えば'A','B','C'をputcでファイルに書き込んで、getcで読み出すとABCの次は-1になっていることはわかりますが。

質問者が選んだベストアンサー

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★ファイルの終了記号『EOF=(-1)』はファイル内に書き込みません。 ・その代わりに Windows などの OS がファイルのサイズを管理していて、そこへの情報を  書き込むことになります。→書き込み後の『fclose』関数などが行っている事になる。 ・質問者さんの例えで行くと『A』『B』『C』という3バイトがファイル・サイズとして、  OS の管理しているファイル情報に記録されます。 ・それで今度は『getc』関数などで読み出すと『A』『B』『C』という3文字(バイト)を  取得しますが、次に1文字を読み出そうとするとOS の管理しているファイル情報より  データがない事が分かるので、終了記号『EOF』を分かりやすく返してくるのです。  決してファイル内に終了記号『EOF』があって、それを読み込んで『EOF=(-1)』を返して  いるわけではありません。→分かりますか?イメージが…。 ・なお、テキストファイルの場合は『^Z=(26)』の文字コードをファイルの終了として処理  する場合があります。昔の MS-DOS という OS ではこれが基本で、ファイルの末尾に『^Z』  を出力して、その後に隠された文章などを記述すると簡単な『秘密文章』が記録できました。  しかし、そのテキストをメモ帳などのソフトで読み込んで上書きすると『秘密文章』をメモリ  に読み込んでいないため削除されてしまいます。→独自のソフトでやり取りする必要があります。 最後に: ・過去に似たような質問がありました。 ・こちらにも『EOF』の詳しい回答を書き込みましたので一度読んでみて下さい。 ・回答者 No.1、No.4 です。→『fgets関数のEOFの扱い方について』 ・以上。おわり。→下の『参考URL』をどうぞ。

参考URL:
http://oshiete1.goo.ne.jp/qa2625434.html
helpcircle
質問者

お礼

とてもよく理解できました。それと、関数が何をやっているかまで理解しないといけないということを感じました。(どれを見たらいいのかはこれから探そうと思います。)ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

少し混乱している気配がしますが... > ファイルの終了記号「EOF(=-1)」っていつ誰が書くのでしょうか。 通常-1に定義されるEOFマクロというのは、ライブラリ関数が返却値として返すものです。これが書き込まれるとすれば、fgetcなどの関数が呼び出し元に戻るとき、あるいは返却値を何らかの変数に代入するときです。 あるいは、FILE型が内部的に管理している「ファイル終了表示子」の意味であれば、fgetcなどの入力関数を呼び出しによって、ファイルの終端に達したときにセットされます。 テキストファイル自体の終端に書き込まれる(ことがある)通常0x1aの値のことであれば、ライブラリ等の実装しだいですが、fclose時に書き込まれる可能性が高いでしょう。

helpcircle
質問者

お礼

-1はライブラリ関数がEOFの返却値として返したもので、読み込んだデータとは違うということが判りました。ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

EOFはファイルの中に存在しているのではありません。 細かく言うとOSによってはそういう可能性もなくはないのですが、WindowsとかUNIX類では そうです。 ファイルの長さなどを管理しているので、ファイルの終端はEOFがあるかどうかを見なくても 判断できます。 たとえばgetcの中に潜ると、 何段か下請け関数を通過してOSのシステムコールまでいきます。 OSに「このファイルの次のデータくれ」と要求して、OSから 「んなもんないよ」という返事が来たら、 getcが -1 (EOF)を返しているというだけのことなのです。 Windows/MS-DOSだとテキストモードでオープンすると、0x1aという値のキャラクタを 見つけると そこでファイルの終わりと見なしますが、基本は同じです。

helpcircle
質問者

お礼

よくわかりました。またgetcの中に潜る方法を探さねばとも思いました。ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 書かれている値のエラーチェックをした後にコピーしたいんですが・・・

    テキストファイルAに書かれている値をエラーチェックをしてから、テキストファイルBにコピーするというプログラムを作るため、とりあえずテキストファイルAをテキストファイルBにコピーするという部分だけ作ってみました。(下に載せておきます) これはきちんと動作したので、つぎにエラーチェック機能(具体的には、aファイルには10以上200未満の正の数が書かれていて欲しいため、エラーチェック機能としては、文字ではなく数字が書かれているか? 書かれている値が10以上200未満か? という2つのチェック機能)をつけようとしたのですが、文字ではなく数字が書かれているか?というチェック機能は作れそうですが、書かれている値が10以上200未満か?というチェック機能がどうすればいいのか分かりません。というのも、下のプログラムは1文字ずつ出力しているためチェック不可能なような・・・ということは根本的に違うのでしょうか? 下のプログラムもテキストを見ながら何とか作成したようなレベルなんで、どなたか助言をお願いします。 #include<stdio.h> #include<process.h> void main(void) { FILE *fp1,*fp3; int a,c; if((fp1=fopen("d:a.txt","r"))==NULL){ printf("aファイルが開けません\n"); exit(1);   } if((fp3=fopen("d:b","w"))==NULL){ printf("bファイルが作成できません\n"); exit(1); } while((a=getc(fp1))!=EOF) putc(a,fp3); fclose(fp3); if((fp3=fopen("d:b.txt","r"))==NULL){ printf("bファイルが開けません\n"); exit(1); } while((c=getc(fp3))!=EOF) putchar(c); fclose(fp1); fclose(fp3); }

  • fgetcの返却値 EOFについて

    C言語について質問です。あまり詳しくないので言葉や、説明等間違っているところが あり読みにくいと思います。 fgetc関数の返却値についてのお伺いします。 EOFはファイルの終わり又は、読み込みが失敗すると、返却されるとあります。 ここで、質問なのですが、2つの違いを判断することは可能でしょうか? 私が行った作業は あるファイル内の文字を1文字づつ読み込んで。 文字の種類ごとに指定したbufferferに格納させたいと思っています。 しかし、ファイル内の終端がEOFで終る場合に読み込みエラーの場合と、読み込み終了で 場合分けができない為うまくできません。 #include <stdio.h> #include <ctype.h> char buffer[100]; char *filename="TestFile"; char* main(){ static FILE *fp = NULL; char *p = buffer; int c; if ( fp == NULL ){ if ((fp = fopen( filename, "r" )) == NULL ){ fprintf(stderr,"can not open file %s\n", filename); return ( (char *)NULL ); } } c = fgetc(fp); while(1){ switch(c){ case '\n': case '\0': *p = '\0'; return( buffer); /*以下のcase EOF の時に2通り考えられる*/ case EOF:/*読み込み終了*/ *p = '\0'; return( buffer); /* case EOF:/*読み込みエラー fprintf(stderr, " OPEN _ERROR %s\n", filename); fclose(fp); fp = NULL; return ( (char *)NULL ); */ default: *p = (char)c; p++; } c = fgetc(fp); } } 以上です。 このような場合どうしたらよいのでしょうか?また異なるやり方があればご教授お願いします。 よろしくお願いします。

  • キャスト方法について

    C言語にてbase64デコード処理を行う独自の関数を作成することになり putcを使用して出力するソース(以下)はあるのですが、 charの配列にデコード結果を上手く格納することができません。 何か良い方法はありませんでしょうか? int main(int argc, char **argv, char **envp) { FILE *fpin, *fpout; int c, i = 0; unsigned char buffer[4]; if( argc < 2 ){ fpin = stdin; } if( argc < 3 ){ fpout = stdout; } else if(( fpout = fopen(argv[2],OPENMODE)) == NULL ){ return 8; } while(( c = getc(fpin) ) != EOF ){ if( c >= 'A' && c <= 'Z' ){ buffer[i++] = c - 'A'; } else if( c >= 'a' && c <= 'z' ){ buffer[i++] = c + 26 - 'a'; } else if( c >= '0' && c <= '9' ){ buffer[i++] = c + 52 - '0'; } else if( c == '+' ){ buffer[i++] = 62; } else if( c == '/' ){ buffer[i++] = 63; } if( i >= 4 || ( i >= 0 && c == '=' )){ putc( ( buffer[0] << 2 ) | ( buffer[1] >> 4 ), fpout); if( i >= 3 )putc( ( buffer[1] << 4 ) | ( buffer[2] >> 2 ), fpout); if( i >= 4 )putc( ( buffer[2] << 6 ) | buffer[3], fpout); i = 0; } } }

  • 続・EOF判定されない

    前回「EOF判定されない」で回答、アドバイスしていただいた a-kumaさん、Haizyさん、inthefloiさん、anisolさん、leaz024さん、cherry-moonさん 本当にありがとうございました。頂いたアドバイスを試行してみましたが、なぜか、ダメでした。(T-T) 環境が悪いのかもしれませんね。 あれから、feof関数を使わずにファイルの終わりを算出して判定するなどの方法を試みましたが、EOF判定だけのために妙に複雑になってしまい、自分でも納得がいかなかったので、再度こちらで皆さんの意見をもらおうと投稿させてもらいました。 今回は質問の仕方を変えて、モジュールの仕様を挙げますので、それから「自分ならこうする」というようなお答えを頂けたらと思っています。 feof関数を使用しても、その他の方法でもなんでもアリです。(^^) 「ファイル一行入力モジュール」(仕様) 1.このモジュールは実行されると「inputfile.txt」から一行だけ(改行まで)読み込み、終了します。次に実行された時は、その次の行を読み込みます。 2.ファイルの終端に達したら、リターンコードに'4'を設定し、終了する。 以上これだけ。(^^; 「inputfile.txt」(仕様) インプットファイルは、テキストファイルで、一行30バイトの文字列を格納しています。ファイルの総バイト数は不定です。 文字コードは「Shift-JIS」「改行=CR+LF」、ファイルの最後にEOF制御文字を設定しています。 「インプットファイルの内容」  1行目 AAAAAAAAAABBBBBBBBBBCCCCCCCCC[改行文字]  2行目 DDDDDDDDDDEEEEEEEEEEFFFFFFFFF[改行文字]           ・           ・           ・ n-1行目 XXXXXXXXXXYYYYYYYYYYZZZZZZZZZ[改行文字]  n行目 [EOF] 「ここはこうしたらいいんじゃないかな?」的な事でかまいませんので、是非みなさんの意見を聞かせてください。

  • 対応する関数ヘッダーがありません

    最近Cを始めたばかりです。 コンパイルできなくて困ってます、意味がわかりません、 誰か教えてください。 #include <stdio.h> #include <process.h> { FILE *fp; int c; if ((fp=fopen("d:abc.txt","w"))==NULL){ printf("Can't open File\n"); exit(1); } while ((c=getchar())!=EOF) putc(c,fp); fclose(fp); } これをコンパイルしたら、 '{' : 対応する関数ヘッダーがありません (旧形式の仮引数リスト?) などと言うエラーメッセージがでます、どうすればいいのか教えてください、なにぶん始めたばかりなので、わかり易くお願いします。

  • EOFにならない?

    元ネタ http://oshiete1.goo.ne.jp/qa3809521.html /* C# */ using System; namespace Q3809521A { class Q3809521A { public static void Main(string[] args) { byte[] b1 = {0x42,0xb9,0xe0,0xa4,0x3b,0xdf,0xea,0xc0,0x3a,0x70,0xeb,0xdc,0x37,0x7c,0xf4,0x8c}; System.IO.FileStream f = new System.IO.FileStream("C:\\hogefuga.bin",System.IO.FileMode.Create, System.IO.FileAccess.Write); f.Write(b1,0,b1.Length); System.Console.WriteLine(BitConverter.ToString(b1)); f.Close(); System.Console.ReadKey(true); } } } という風に作ったhogefuga.binを bccでコンパイルした以下のプログラムで読み込ませたところ, #include <iostream> #include <fstream> int main () { unsigned char buf[4]; float *hoge; std::ifstream ifs ( "hogefuga.bin" , std::ifstream::in ); while(!ifs.eof()){ // Debug // std::cout << (ifs.eof() == true ? "TRUE" : "FALSE") << std::endl ; for (int i = 0;i < 4;i++ ){ buf[3 - i] = (unsigned char) ifs.get(); } hoge = (float *)buf; std::cout << (*hoge) <<std::endl; } ifs.close(); return 0; } 92.9388 0.0068334 0.000919042 1.50773e-05 と、期待通り表示された後も ifs.eof()がtrueにならず,続きを読み込もうとして クラッシュします。 どうやって回避するのが普通なのでしょう? #バイト数を先に把握するってのも一つの手かもしれないけど,普通じゃないような気がする

  • C言語において、=と==の違いって何ですか?

    C言語でプログラムを組むなかで例えば、 x = a + b 等の数式ではただの = 一個を使いますよね? だけど、 !=EOF においては使っているのは == ですよね? 基本的なことだとは分かっているのですがこの違いって何なんでしょうか?

  • C言語の<ctype.h>のisspace()について教えてください。

    C言語の<ctype.h>のisspace()について教えてください。 まだ初心者なので、変な質問でしたらすみません。 ライブラリで用意されているisspace()関数があります。 空白類の文字判定を行えるとあり、引数はint型で指定することになっています。 そこで疑問なのですが文字列をgetcで取ってきた時にcはEOFの時にマイナスを取るわけですが、問題ないのでしょうか? 例えば int c; while( !isspace( c = getc( fp )) && c != EOF ){・・・ getcを(unsigned char)ででもキャストすると解消するとは思いますが、問題ないのならば加えたくありません・・。以上ですが、分かりにくい説明でご迷惑おかけします。 よろしくお願い致します。

  • 途中にEOFがあるファイルの読込

    VB6でファイルを全行読み込んで任意の処理を行いたいのですが、そのファイルには 途中に文字コード 1a (つまりEOF)が入っている場合があります。 普通に Line Input で処理すると、その部分でファイル終了と判断し 読込を終えてしまいますが、その後のデータも読み込みたいのです。 どのようにすれば良いのでしょうか?

  • 【至急!数学・中学生程度】教えて下さい3

    a,b,c3つの整数がある、ab<0、abc<0、a+c<0のとき、次のうち正しいものを選び記号で答えなさい。 (ア)a<0、b<0、c<0 (イ)a>0、b<0、c<0 (ウ)a<0、b>0、c>0 ================================================ 簡単な解説も入れて頂けると、勉強になります。 よろしくお願いします。

電話予約方法
このQ&Aのポイント
  • 電話予約方法についてのお困りごとやトラブルの解決方法をご紹介します。
  • パソコンやスマートフォンのOSや接続方法、関連するソフト・アプリについて詳しく教えてください。
  • ブラザー製品の電話予約に関する質問にお答えします。お困りの内容を教えてください。
回答を見る