【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.22763

fgetsによるファイルからの読み込み
投稿者---仁(2005/08/21 01:21:59)


fgets関数を使用したファイルからの読み込みの処理ですが、

while文のループで、fgetsがNULLでない間繰り返していますが、
単に、NULLでない間という判定だけで良いのですか。

#include <stdio.h>

main()
{
    FILE *fp;
    char buff[256] ;

    fp = fopen("text.txt","r");
    if (fp == NULL) {
        printf("file open error\n");
        exit(1);
    }

    while(fgets(buff,sizeof buff,fp)!=NULL) {
        printf("[%s]\n",buff);
    }

    if(0 != fclose(fp)) {
        printf("file close error\n");
        exit(2);
    }
}


fgetsがNULLになるのは、読み込みがエラーになった場合か、
ファイルがEOFの場合かと。
本来は、この判断をつけるべきなのでしょうか。

if (ferror(fp)) {
    puts("Read Error !!");
    exit(3);
}
if (feof(fp)) {
    break;
}


while(fgets(buff,sizeof buff,fp)!=NULL) {
で処理をされているのを見かけます。
この掲示板のサンプルでもありますが。



この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:fgetsによるファイルからの読み込み 22764 まきじ 2005/08/21 01:40:59
<子記事> Re:fgetsによるファイルからの読み込み 22765 かずま 2005/08/21 14:33:18
<子記事> Re:fgetsによるファイルからの読み込み 22766 2005/08/21 18:51:09


No.22764

Re:fgetsによるファイルからの読み込み
投稿者---まきじ(2005/08/21 01:40:59)


>fgetsがNULLになるのは、読み込みがエラーになった場合か、
>ファイルがEOFの場合かと。

それで、何か問題があるのでしょうか?

>本来は、この判断をつけるべきなのでしょうか。
>ferror(fp)

ferror() は読み取りエラーや書き込みエラーが発生したか否かなので
EOF に到達しても 非0 を返しエラーとなりません。

>feof(fp)

feof() はEOFに到達したか否かなので
読み取りエラーが発生しても読み取りを続行します。


読み取りエラーを無視したい場合は、feof() で判断しても良いですが、
読み取りエラーの時に、何らかの処理をする場合は、ferror() か
fgets() の戻り値で判断する必要があります。


この投稿にコメントする

削除パスワード

No.22765

Re:fgetsによるファイルからの読み込み
投稿者---かずま(2005/08/21 14:33:18)


> fgetsがNULLになるのは、読み込みがエラーになった場合か、
> ファイルがEOFの場合かと。
> 本来は、この判断をつけるべきなのでしょうか。

つけてもかまいませんが、while ループを抜けてからで十分でしょう。
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    FILE *fp;  char buff[256];

    fp = fopen("text.txt","r");
    if (fp == NULL) puts("file open error"), exit(1);

    while (fgets(buff, sizeof buff, fp) != NULL)
        printf("> %s", buff);

    if (ferror(fp)) puts("file read error"), exit(3);
    if (fclose(fp) != 0) puts("file close error"), exit(2);
    return 0;
}

ferror(fp) が発生するときは、fclose(fp) もエラーになるので、そちらに
まとめて、エラーとしてしまうこともできます。

ferror(fp) が発生するのは、リムーバブルメディア(CD-ROM やフロッピー
ディスクなど)が read中に取り出されたときだとか、ファイルシステムに
不整合があるときなどの異常事態で、通常は起こりにくいので、チェック
しないことが多いだけです。


この投稿にコメントする

削除パスワード

No.22766

Re:fgetsによるファイルからの読み込み
投稿者---仁(2005/08/21 18:51:09)


ありがとうございます。

ferror、feofを使うにしてもいろいろなのですね。

かずまさんがおっしゃるとおり、ループ内よりも外が良い気がします。
fgetsで読み込んでいるわけですから、読み込めた=正常としても良い
わけですか。
NULLだったときに参照するのが良いかもしれません。

まきじさんがおっしゃるとおり、
ferrorは、EOFだったとしても正常を返しますし。
feofは、エラーとしても終端に達しているか否かですから、続きますね。
fgets、ferrorの組み合わせですね。

while(fgets(buff,sizeof buff,fp)!=NULL) {
    if (feof(fp)) {
    break;
}

は、どっちが早いのですか。
その様につくっているから終端が先。

終端の後に続くなって不完全なファイル作ろうと思えば作れるんですか。



この投稿にコメントする

削除パスワード

No.22767

Re:fgetsによるファイルからの読み込み
投稿者---まきじ(2005/08/21 19:04:59)


>fgets、ferrorの組み合わせですね。

feof() と ferror() の組み合わせ。
while(!feof(fp)){
    fgets(buff,sizeof buff,fp);
    if(!ferror(fp)) break;
}

>どっちが早いのですか。

何と何?

>その様につくっているから終端が先。

どの様に?

>終端の後に続くなって不完全なファイル作ろうと思えば作れるんですか。

終端(EOF)の後には書き込めないはずです。


この投稿にコメントする

削除パスワード

No.22769

Re:fgetsによるファイルからの読み込み
投稿者---かずま(2005/08/21 22:56:02)


> while(!feof(fp)){
>     fgets(buff,sizeof buff,fp);
>     if(!ferror(fp)) break;
> }

読み込んだ buff の処理をどこに書くつもりですか?
feof(fp) は fgets() の実行後でなければ意味がありません。



この投稿にコメントする

削除パスワード

No.22770

Re:fgetsによるファイルからの読み込み
投稿者---まきじ(2005/08/21 23:36:12)


>読み込んだ buff の処理をどこに書くつもりですか?
>feof(fp) は fgets() の実行後でなければ意味がありません。

そうですね。訂正しときます。
fgets(buff,sizeof buff,fp);
while(!ferror(fp) && !feof(fp)){
    printf("%s\n",buff);  //処理
    fgets(buff,sizeof buff,fp);
}



この投稿にコメントする

削除パスワード

No.22773

Re:fgetsによるファイルからの読み込み
投稿者---仁(2005/08/22 11:50:55)


ありがとうございます。

とんちんかんな質問をしてすみません。
色々とアドバイスありがとうございます。





この投稿にコメントする

削除パスワード

No.22781

Re:fgetsによるファイルからの読み込み
投稿者---かずま(2005/08/23 02:22:59)


> fgets(buff,sizeof buff,fp);
> while(!ferror(fp) && !feof(fp)){
>     printf("%s\n",buff);  //処理
>     fgets(buff,sizeof buff,fp);
> }

次のプログラムとどこが違うんでしょうか?

    while (fgets(buff, sizeof buff, fp) != NULL)
        fputs(buff, stdout);


元の質問は、fgets() が NULL を返さなかった場合、EOF 以外に error の
可能性があるのに、なぜそれをチェックしないのか、というものだったはず
です。ferror(fp) と feof(fp) を同じように扱っては意味がありません。

私は、while ループを抜けてから判断すればよい。また、ferror() のチェック
が省略されるのには、それなりの意味があるという回答をしています。



この投稿にコメントする

削除パスワード

No.22783

Re:fgetsによるファイルからの読み込み
投稿者---まきじ(2005/08/23 09:32:39)


22765 の かずまさんのレスの

>ferror(fp) が発生するのは、リムーバブルメディア(CD-ROM やフロッピー
>ディスクなど)が read中に取り出されたときだとか、ファイルシステムに
>不整合があるときなどの異常事態で、通常は起こりにくいので、チェック
>しないことが多いだけです。

で、ferror() のチェックはループを抜けてからで良い事には
納得してますが、

22763 で仁さんは

>fgetsがNULLになるのは、読み込みがエラーになった場合か、
>ファイルがEOFの場合かと。

と仰ってるのに、質問が、

>while文のループで、fgetsがNULLでない間繰り返していますが、
>単に、NULLでない間という判定だけで良いのですか。

だったので、

fgets() != NULL で、読み取りエラーでも EOF でもループを抜ける事を示し
「feof() と ferror() の組み合わせでもできる」という事が言いたかった。

ことレスしたつもりでした。


この投稿にコメントする

削除パスワード

No.22768

Re:fgetsによるファイルからの読み込み
投稿者---かずま(2005/08/21 22:55:18)


> while(fgets(buff,sizeof buff,fp)!=NULL) {
>     if (feof(fp)) {
>     break;
> }

無意味な if文です。
fgets() が NULL のとき、feof(fp) は常にゼロですから。
それから、{ と } の対応が取れていません。



この投稿にコメントする

削除パスワード

No.22775

Re:fgetsによるファイルからの読み込み
投稿者---RiSK(2005/08/22 12:41:43)


> fgets() が NULL のとき、feof(fp) は常にゼロですから。

fgets() が != NULL のとき、feof(fp) は常にゼロ

の間違いです。


この投稿にコメントする

削除パスワード

No.22777

Re:fgetsによるファイルからの読み込み
投稿者---RAPT(2005/08/22 23:09:20)


補足すると、feof(), ferror()は先読みしません。
直前のファイル処理の際の結果状態を取得します。

それゆえ、fgets()が非NULLを返しているということは、
処理が成功しているため、feof(), ferror()共に0を返します。

今回のケースでfeof(), ferror()を使用するタイミングは、
既にかずまさんが示したとおり、fgets()がNULLを返した直後となるはずです。



この投稿にコメントする

削除パスワード

No.22778

Re:fgetsによるファイルからの読み込み
投稿者---仁(2005/08/22 23:42:53)


皆様方ありがとうございます。

アドバイス等参考にさせて頂ます。



この投稿にコメントする

削除パスワード

No.22780

Re:fgetsによるファイルからの読み込み
投稿者---かずま(2005/08/23 02:10:21)


>> fgets() が NULL のとき、feof(fp) は常にゼロですから。

> fgets() が != NULL のとき、feof(fp) は常にゼロ
> の間違いです。

そのとおりです。
「fgets() が NULL でないとき、」と書いたつもりでいました。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧