電子書籍の厳選無料作品が豊富!

#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が返ったら終了だと思うのですが…

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

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

A 回答 (3件)

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が返り、上と同様にループは終了します。


どこら辺で無限ループになる、とお考えですか?
    • good
    • 0
この回答へのお礼

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

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

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

お礼日時:2010/02/23 23:09

標準入力から、「EOF」を入力するには、


「CTRL+Z」だったかと思います。

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

参考までにどうぞ。
    • good
    • 0
この回答へのお礼

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

お礼日時:2010/02/23 22:59

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

*/
return EOF;
}
最初の文字を読み込んで EOF なら「 return EOF 」なので 下には行かず 戻るのでは?
    • good
    • 0
この回答へのお礼

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

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

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

お礼日時:2010/02/23 22:56

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