dポイントプレゼントキャンペーン実施中!

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に返ってくるのでしょう?

A 回答 (8件)

解決したのかな~



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

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

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

で、

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

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

読み込み関数が正常以外を返してきたときに、EOF なのか Error なのかを判別する
ために存在します(ferror の裏)。あなたの考え方であってますよ。
    • good
    • 0

HAIZY@のーみそ・とろ~んだった(過去形)です。



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


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

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

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

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

leaz024さんが言われている事は、その通りだと思うのですが、それ以前に、fgetsに問題があります。


fgetsの戻り値がNULLになるのは、ファイルの終端以降を読み込もうとしたか、何らかのエラーが発生した場合です。

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

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

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

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

leaz024さんに加えて、ちょっと指摘しておきます。

[EOF]のコードは正しいですか?MS-DOSでは[EOF]のコードは1AHですが、stdio.hではFFHと定義されているようです。1AHになっているか確認してみてください。

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

何やら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バイトになっていないか確認してみて下さい。
    • good
    • 0

ふたたび


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)==0)
  rtn_code[0] = '8'; /*ファイルの終わりではない(エラー)*/
else
  rtn_code[0] = '4'; /*ファイルの終わり*/

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

私は逆の理解をしてるんだろか・・・
(実は自信がないんです、コレに関しては・・・)(--;

補足日時:2001/10/25 20:29
    • good
    • 0

fgets で NULL が帰ってきちゃってるから、


その if 文の中に入ってない。
だから、rtn_code[0] の中身が '8' のままってことなんじゃないですか?
    • good
    • 0

>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 以外の戻り値の場合の動作を考えてみてください。(^^;

でわ。

この回答への補足

Haizyさん、こんばんわ。

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

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

それから質問の補足ですが、ファイルは"rb"(バイナリモード)で
開いています。

補足日時:2001/10/25 17:32
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


このQ&Aを見た人がよく見るQ&A