こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

C言語の関数の戻り値がおかしい?

#include<stdio.h>
#include<ctype.h>
#include<stdlib.h>

int get_word(char *buf,int buf_size,FILE *fp)
{
int len;
int ch;

while((ch = getc(fp)) != EOF && !isalnum(ch));/*→「英数字のとき」このループは飛ばす。*/

if(ch == EOF){/*もし英数字以外が入力されていたらメインプログラムにEOFを返す。*/
return EOF;
}

len = 0;
do{
buf[len] = ch;
len++;
if(len >= buf_size){
fprintf(stderr,"word too long.\n");
exit(1);
}
}while((ch = getc(fp)) != EOF && isalnum(ch));
buf[len] = '\0';

return len;

}

int main(void)
{

char buf[256];

while(get_word(buf,256,stdin) != EOF){
printf("<<%s>>\n",buf);
}

return 0;
}

C言語ポインタ完全制覇という本のP67に載っていたプログラムをそのまま載せています。

get_word関数の中のif文で、EOFを返した時もループwhile(get_word(buf,256,stdin)により再入力するようなプログラムになっています。でも、「!=EOF」と記述されているのだから、EOFが返ったら終了だと思うのですが…

なぜ再入力し続けるプログラム(無限ループ)になってしまっているのでしょうか?

というか、私の環境で動作させたらおかしいだけじゃないでしょうか?
よろしくお願いします。

投稿日時 - 2010-02-23 22:21:03

QNo.5701174

困ってます

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

1> while((ch = getc(fp)) != EOF && !isalnum(ch)); /*→「英数字のとき」このループは飛ばす。*/

2>if(ch == EOF){/*もし英数字以外が入力されていたらメインプログラムにEOFを返す。*/
2>return EOF;
2>}

(略)
3>}while((ch = getc(fp)) != EOF && isalnum(ch));
3>buf[len] = '\0';

便宜上、番号を付けました
・「get_word関数の中のif文で、EOFを返した時」とは 2> のことですか?
それなら、これでEOFが返れば
>while(get_word(buf,256,stdin) != EOF){
が while(EOF != EOF)→while( 偽 )となりループが終了します。

3>でEOFになった場合も、次の呼び出しで getc()がEOFになるので、2>でEOFが返り、上と同様にループは終了します。


どこら辺で無限ループになる、とお考えですか?

投稿日時 - 2010-02-23 23:05:25

お礼

ですよね。
理屈としてはkmeeさんがおっしゃっているように、ループは
終了する処理になってます。

とりあえず、客観的にこのプログラムは正しいと思うので
質問は締め切らせていただきます。

おさん方回答ありがとうございました^^

投稿日時 - 2010-02-23 23:09:25

ANo.3

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

標準入力から、「EOF」を入力するには、
「CTRL+Z」だったかと思います。

処理系によってはやり方が違うかもしれません。

参考までにどうぞ。

投稿日時 - 2010-02-23 22:41:38

お礼

せっかく回答していただいたのに申し訳ないのですが、標準入力
からEOFを入力させるプログラムではないです。
私の書き方がまずかったかもしれませんが…
関数get_wordによる戻り値がEOFならば、メイン関数の方の
ループを抜けるのではないかと思ったのですが、少なくとも
私の環境では抜けないのです。

投稿日時 - 2010-02-23 22:59:42

ANo.1

>if(ch == EOF){/*もし英数字以外が入力されていたらメインプログラムにEOFを返す。*/
return EOF;
}
最初の文字を読み込んで EOF なら「 return EOF 」なので 下には行かず 戻るのでは?

投稿日時 - 2010-02-23 22:37:38

お礼

そうですね。
戻るならば、
while(get_word(buf,256,stdin) != EOF){
printf("<<%s>>\n",buf);
}

の「get_word(buf,256,stdin) != EOF」部分の処理により
ループを脱出するのではないかと思ったのです。

ところが、私の環境ではstdinにより「*?」などの文字以外を入力
して引数にしても、またメイン関数でstdinによる再入力を
することになると言った動作になってしまっているのです。

投稿日時 - 2010-02-23 22:56:04