OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
締切り
済み

EOF判定されない

  • すぐに回答を!
  • 質問No.157318
  • 閲覧数1429
  • ありがとう数5
  • 気になる数0
  • 回答数8
  • コメント数0

お礼率 59% (34/57)

if(fgets(buff, 21, fp) == NULL)
{
  if(!feof(fp))
  {
    rtn_code[0] = '8';
  }
  else
  {
    rtn_code[0] = '4';
  }
}
--------------------------------------

/入力ファイル/
--------------------------------------

1行目 AAAAABBBBBCCCCCDDDD[LF]
2行目 EEEEEFFFFFGGGGGHHHH[LF]
3行目 [EOF]

--------------------------------------
[LF]=改行文字です。
[EOF]=ファイル終端指示子です。

上記のプログラムは、
1行20バイトある入力ファイルから一行だけgetするサブモジュールの一部です。
3回目にこれを実行した時に、EOFになってrtn_codeが'4'で返ってくる予定なのですが、どうしても非EOFになって'8'が返ってきてしまうのです。
なぜなんでしょうか?

そもそも、どうなるとEOF指示子がfpに返ってくるのでしょう?
通報する
  • 回答数8
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

回答 (全8件)

  • 回答No.3
レベル13

ベストアンサー率 40% (404/988)

ふたたび if(feof(fp)) あれあれ?? このままじゃ、上のif分って、0 = False じゃ無いですか???(^^; if(feof(fp)==0)   rtn_code[0] = '4'; else   rtn_code[0] = '8'; じゃないと、True返らないですねぇ~~!!   m( _ _;)m・・ ...続きを読む
ふたたび
if(feof(fp))

あれあれ??
このままじゃ、上のif分って、0 = False じゃ無いですか???(^^;

if(feof(fp)==0)
  rtn_code[0] = '4';
else
  rtn_code[0] = '8';
じゃないと、True返らないですねぇ~~!!

  m( _ _;)m・・・老いたな<俺

でわ~~。
補足コメント
techtak

お礼率 59% (34/57)

え?
それって逆ではないんですか?

if(feof(fp)==0)
  rtn_code[0] = '8'; /*ファイルの終わりではない(エラー)*/
else
  rtn_code[0] = '4'; /*ファイルの終わり*/

参考書には
「エンドオブファイル指示子がセットされている時、feof関数は非0を返し、
それ以外は0を返す。」
と、あります。

私は逆の理解をしてるんだろか・・・
(実は自信がないんです、コレに関しては・・・)(--;
投稿日時 - 2001-10-25 20:29:18
  • 回答No.2
レベル9

ベストアンサー率 36% (37/102)

fgets で NULL が帰ってきちゃってるから、 その if 文の中に入ってない。 だから、rtn_code[0] の中身が '8' のままってことなんじゃないですか?
fgets で NULL が帰ってきちゃってるから、
その if 文の中に入ってない。
だから、rtn_code[0] の中身が '8' のままってことなんじゃないですか?
  • 回答No.1
レベル13

ベストアンサー率 40% (404/988)

>feof は,指定したストリーム上の最後の入力操作で >ファイル終了標識が検出されると 0 以外の値を返し, >ファイル終了標識に達しなければ 0 を返します。 2行目に注目。終了の場合は、0以外です。 何が返ってくるかわからないんですね~。 この条件で、戻り値8を非EOFとしたいならば、 if(!feof(fp)) でなく、 if(feof(fp))   rtn_c ...続きを読む
>feof は,指定したストリーム上の最後の入力操作で
>ファイル終了標識が検出されると 0 以外の値を返し,
>ファイル終了標識に達しなければ 0 を返します。

2行目に注目。終了の場合は、0以外です。
何が返ってくるかわからないんですね~。

この条件で、戻り値8を非EOFとしたいならば、

if(!feof(fp))
でなく、

if(feof(fp))
  rtn_code[0] = '4';
else
  rtn_code[0] = '8';


の方が良くないですか?
NOT処理は、ない方が1サイクル分処理が早いですし、なによりバグになりかねません。(多用すると、バグの元です。)
<<0/1 以外の戻り値の場合の動作を考えてみてください。(^^;

でわ。
補足コメント
techtak

お礼率 59% (34/57)

Haizyさん、こんばんわ。

確かにNOT処理はよくなかったです。(^^;
で、アドバイスの通りにしてみましたが、
やはり状況は変わりませんでした。

もう丸一日、参考書やWebで調べまくっていろいろやってみたのですが
どうしても解決できないのです。
ここが最後の砦です!

それから質問の補足ですが、ファイルは"rb"(バイナリモード)で
開いています。
投稿日時 - 2001-10-25 17:32:54
  • 回答No.4
レベル12

ベストアンサー率 75% (398/526)

何やらfeofで揉めてますが、質問にある使い方に問題はないように思えます。 ところで改行文字[LF]と書いてありますが、これは確実ですか? Cでは改行を[\n]という一文字で片付けてしまいますが、単なるWindowsのテキストファイルだと、実際には[CR][LF]という2バイトになっています。 テキストモードなら、[CR][LF]→[\n]と変換して1バイトで拾ってくれますが、バイナリモード ...続きを読む
何やらfeofで揉めてますが、質問にある使い方に問題はないように思えます。

ところで改行文字[LF]と書いてありますが、これは確実ですか?
Cでは改行を[\n]という一文字で片付けてしまいますが、単なるWindowsのテキストファイルだと、実際には[CR][LF]という2バイトになっています。

テキストモードなら、[CR][LF]→[\n]と変換して1バイトで拾ってくれますが、バイナリモードだとそのまま2バイトで拾ってしまいます。

つまり、buffの中身は、
1回目:AAAAABBBBBCCCCCDDDD[CR]\0
2回目:[LF]\0
3回目:EEEEEFFFFFGGGGGHHHH[CR]\0
となり、まだ[LF]が残っているのでfeofは0を返します。

ファイルサイズを見るなどして、改行文字が2バイトになっていないか確認してみて下さい。
  • 回答No.5
レベル11

ベストアンサー率 48% (146/301)

leaz024さんに加えて、ちょっと指摘しておきます。[EOF]のコードは正しいですか?MS-DOSでは[EOF]のコードは1AHですが、stdio.hではFFHと定義されているようです。1AHになっているか確認してみてください。 (なお、私はC言語はほとんどわからないのですが、興味があったので昔のパソコンで調べてみました。的外れなアドバイスだったら無視してください)
leaz024さんに加えて、ちょっと指摘しておきます。[EOF]のコードは正しいですか?MS-DOSでは[EOF]のコードは1AHですが、stdio.hではFFHと定義されているようです。1AHになっているか確認してみてください。

(なお、私はC言語はほとんどわからないのですが、興味があったので昔のパソコンで調べてみました。的外れなアドバイスだったら無視してください)
  • 回答No.7
レベル13

ベストアンサー率 40% (404/988)

HAIZY@のーみそ・とろ~んだった(過去形)です。 #3 について はい、逆です。間違えました。ゴメンナサイ。 今回の教訓: 本職(コンピュータ関係)がトラブってるの時は、回答しない方が良い(笑) 混乱を招き、本当に申し訳ございません。 ●デバックのツールで解析してみましょう。 トレース と ブレークポイントを駆使し、「監視式」で各変数に何が入っているのか、監視してみる。 ...続きを読む
HAIZY@のーみそ・とろ~んだった(過去形)です。

#3 について
はい、逆です。間違えました。ゴメンナサイ。
今回の教訓:
本職(コンピュータ関係)がトラブってるの時は、回答しない方が良い(笑)
混乱を招き、本当に申し訳ございません。


●デバックのツールで解析してみましょう。
トレース と ブレークポイントを駆使し、「監視式」で各変数に何が入っているのか、監視してみる。

if(feof(fp))
を式評価してみる。

if (gets(buff, 21, fp))
buff の最大容量を考慮した上で、21 を大きくしてみる。
結果どうなるか。
buffの値を監視式で見てみる。(16進表示が良い。)

単純なデバッグ作業です。
「わたしなら、こうします」と言う感じです。
参考になれば。
  • 回答No.6

leaz024さんが言われている事は、その通りだと思うのですが、それ以前に、fgetsに問題があります。 fgetsの戻り値がNULLになるのは、ファイルの終端以降を読み込もうとしたか、何らかのエラーが発生した場合です。 特別なエラー処理が必要ないのでしたら、まずはファイルオープンで"rb"を"rt"にして、 if (gets(buff, 21, fp ...続きを読む
leaz024さんが言われている事は、その通りだと思うのですが、それ以前に、fgetsに問題があります。
fgetsの戻り値がNULLになるのは、ファイルの終端以降を読み込もうとしたか、何らかのエラーが発生した場合です。

特別なエラー処理が必要ないのでしたら、まずはファイルオープンで"rb"を"rt"にして、

if (gets(buff, 21, fp))
{
rtn_code[0] = '8';
}
else
{
rtn_code[0] = '4';
}

というようにされてはどうでしょうか?

それから、EOFがファイルの終端に付加されるかどうかはテキストエディタ及びオプションしだいです。
  • 回答No.8
レベル14

ベストアンサー率 50% (1122/2211)

解決したのかな~ 状況は想像するしかないのですが、多分、No.4 の leaz024 さんの回答で解決する 問題だと思います。 > [EOF]=ファイル終端指示子です。 なんて書いているあたりが、Windows(MS-DOS を引きずっている)っぽい。 で、 > そもそも、どうなるとEOF指示子がfpに返ってくるのでしょう? についてなんですが、直前の読 ...続きを読む
解決したのかな~

状況は想像するしかないのですが、多分、No.4 の leaz024 さんの回答で解決する
問題だと思います。

> [EOF]=ファイル終端指示子です。

なんて書いているあたりが、Windows(MS-DOS を引きずっている)っぽい。

で、

> そもそも、どうなるとEOF指示子がfpに返ってくるのでしょう?

についてなんですが、直前の読み込み処理(fgets に限らず fgetc や fread でも
良い)において、既に EOF が検出されていた場合に、ゼロ以外を、そうじゃないとき
にはゼロを返します。

読み込み関数が正常以外を返してきたときに、EOF なのか Error なのかを判別する
ために存在します(ferror の裏)。あなたの考え方であってますよ。
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ