キーボードから整数値を入力してなにがしかの処理をし
EOF(ctrl+z)で終了とする以下のようなプログラムが
あります。
******************************************
#include <stdio.h>
#define MAX 100
#define KETA 20
void main(void)
{
char c, s[KETA];
int i, num;
printf("整数値を入力\n");
c = fgets(s, KETA, stdin);
num = atoi(s);
//for(i = 0; (num != EOF && i < MAX); i++){ ×
//for(i = 0; (s[0] != EOF && i < MAX); i++){×
//for(i = 0; (c != NULL && i < MAX); i++){ ×
for(i = 0; (c != 0 && i < MAX); i++){ //○
/*****何某かの処理*****/
fflush(stdin);
c = fgets(s, KETA, stdin);
num = atoi(s);
}
}
******************************************
このときのfor文で、上記にあるようにEOFやNULLが取得
されず正しく動作しません。コンパイルはできますが、
ステップ実行すると"シンボルエラー"と出ます。
stdio.hにはEOFもNULLもそれぞれ-1、0と定義されています。
(getcharやscanfだと、EOFは取得できます。)
.net 2005で行っています。
これらの原因が何なのか、ご存知の方おりましたらご教授
下さいますよう、宜しくお願いします。
atoi()を使うにはstdlib.hが必要なようです。
また、atoi()にEOFやNULLを渡したときに何をするかMSDNを見る限りはわからないため
atoi()の前に判定を入れて
c = fgets(s, KETA, stdin); // EOFを読んだか if (c == NULL) { // 終了させる処理など // 12行目付近なら return 0; とか // 20行目付近なら break; とか } // NULLを読んだか if (strlen(s) == 0) { // 同上 } num = atoi(s);
というような感じでいかがでしょうか。
atoi、_atoi_l、_wtoi、_wtoi_l http://msdn2.microsoft.com/ja-jp/library/yd5xkb5c(VS.80).aspx
fgets、fgetws http://msdn2.microsoft.com/ja-jp/library/c37dh6kf(VS.80).aspx
(URL自動リンクが途切れていますので注意してください)
http://homepage1.nifty.com/MADIA/vc/C/c_lang_ansi19.htm
まず、fgetsは
char *fgets( char *string, int n, FILE *stream );
なので、char形のcで戻り値を受けるのはおかしいです。
char *c, s[KETA];にして下さい。
あと、fgetはEOFかエラーの時NULLを返すのでEOFは戻り値として返しません。
回答者 | 回答 | 受取 | ベストアンサー | 回答時間 | |
---|---|---|---|---|---|
1 | Vacuum | 55回 | 37回 | 4回 | 2008-01-07 17:06:25 |
私の調べ方に不足がありまして、申し訳ありませんでした。
fgets関数の戻り値は、正常時はchar型のポインタ(上記の
プログラムで言うと引数s)、ファイル終了またはエラー時:NULL
ということで、
・fgetsの戻り値を得るならchar型ポインタ
・fgetsはEOFを返すことはない
ようです。
よって、上記の変数Cを*cに変えれば、上から3番目のfor文は
正常に動きました。お騒がせ致しました。
blueberrystreamさん
申し訳ありません、<stdlib.h>は書き忘れです。
そして、上記のプログラムでは、fgetsの戻り値としてはNULLを
受け取ることはあっても、上記で言うs[]配列にはNULLは入らず、
s[]はその前の入力値を保持し、結果的にatoi関数にはNULLは
渡らないようです。
ちなみに、強引に
num = atoi(NULL);
や
num = atoi((char *)NULL);
などとすると、コンパイルは通りますが、実行エラーになりました。
(それ以上の追求は、一端お休みしようかと思います。)
ご回答くださり、ありがとうございました。