ページ 1 / 1
入力関数について
Posted: 2007年4月03日(火) 23:16
by 大工
#include <stdio.h>
#define Correct 1
#define Error 0
enum eScale { binary, octal, hexadecimal, decimal, } scale_pat;
void input_scale(int scale_pat);
int main (void){
int cnt, check;
char msg[10];
printf("Please choose the following\n\n");
printf("binary scale : 1\noctal scale : 2\nhexadecimal scale : 3\ndecimal scale : 4\n\n");
printf("Please input >>>");
do{
scanf("%d", &cnt);
switch(cnt){
case 1:
input_scale(binary);
check = Correct;
break;
case 2:
input_scale(octal);
check = Correct;
break;
case 3:
input_scale(hexadecimal);
check = Correct;
break;
case 4:
input_scale(decimal);
check = Correct;
break;
default :
printf("*Error*\n");
printf("Please input different value >>>");
check = Error;
break;
}
}while(check == Error);
return 0;
}
void input_scale(const int scale_pat){
int a;
char msg[10];
gets(msg);
printf("test is %s\n", msg);
return;
}
いま作っているプログラムは途中なので目的は伏せて起きます.
input_scale関数(現在はテスト中なので内容は変わりますが)内でgets(msg)がうまく動いてくれません。ですがscanf("%s", msg)とするとうまく動いてくれます。
どうしてこのような事態がおこってしまうんでしょうか?
あと、よかったらで良いのですがscanf(" %d", &val)でa(文字)を入力したとしたら暴走しますがこれを回避するために一度文字列として入力して(getsを用いて)それをisdigitを使って判断し、それからungetcを使ってバッファにもどしscanfを使ってとりこんだほうが効率てきなのでしょうか?
Re:入力関数について
Posted: 2007年4月03日(火) 23:46
by 組木紙織
最初にscanf()したときにバッファに'\n'が残っており、その状態でgets()を使ったので'\n'のみが読み込まれ、
gets()は'\n'を'\0'に変換し、最終的にmsg[10]に入るのは'\0'だけとなるのでうまく動かないのではないかと思います。
>あと、よかったらで良いのですがscanf(" %d", &val)でa(文字)を入力したとしたら暴走しますがこれを回避するために一度文字列として入力して(getsを用いて)それをisdigitを使って判断し、それからungetcを使ってバッファにもどしscanfを使ってとりこんだほうが効率てきなのでしょうか
gets()で取り込んだならsscanf()を使ったらよいのではないかと思います。戻り値を調べれば判断できたと思います。
一度バッファに戻すとその分だけ効率が落ちるような気がするので。
Re:入力関数について
Posted: 2007年4月04日(水) 00:17
by 大工
返信ありがとうございます。
fflushを使ってバッファクリアしようと思ったのですがうまくいきません><;
Re:入力関数について
Posted: 2007年4月04日(水) 08:07
by 組木紙織
fflushは出力に対して効果がある関数だったはずなので、
rewind(stdin)
を使ったらどうでしょうか?
Re:入力関数について
Posted: 2007年4月04日(水) 12:09
by 大工
ん~・・・それでも動いてくれません><;
Re:入力関数について
Posted: 2007年4月04日(水) 13:05
by miyaza
>ん~・・・それでも動いてくれません><;
rewind()を使う場所がおかしいんじゃないですか?
まあ、ソースが無いので予想ですが。
具体的にどのように修正したかを書かないと適切な回答を得るのが難しくなると思います。
Re:入力関数について
Posted: 2007年4月04日(水) 14:08
by 大工
#include <stdio.h>
#include <stdlib.h>
#define Correct 1
#define Error 0
enum eScale { binary, octal, hexadecimal, decimal, } scale_pat;
void input_scale(int scale_pat);
void f_binary(char value[/url], int b_null);
int main (void){
int cnt, check;
char msg[10];
printf("Please choose the following\n\n");
printf("binary scale : 1\noctal scale : 2\nhexadecimal scale : 3\ndecimal scale : 4\n\n");
printf("Please input >>>");
do{
scanf(" %d", &cnt);
rewind(stdin);
switch(cnt){
case 1:
input_scale(binary);
check = Correct;
break;
case 2:
input_scale(octal);
check = Correct;
break;
case 3:
input_scale(hexadecimal);
check = Correct;
break;
case 4:
input_scale(decimal);
check = Correct;
break;
default :
printf("*Error*\n");
printf("Please input different value >>>");
check = Error;
break;
}
}while(check == Error);
return 0;
}
void input_scale(const int scale_pat){
int a, cnt, check;
char scale[10];
gets(scale);
switch(scale_pat){
case binary:
for(cnt = 0, check = 0; scale[cnt] != '\0'; cnt++){
if(scale[cnt] == '0' || scale[cnt] == '1') check++;
}
printf("check == %d, cnt == %d\n", check, cnt);
if(check == cnt) f_binary(scale, check);
else{
printf("*Error*\n");//エラー時に強制終了する.
exit(EXIT_FAILURE);
}
break;
case octal:
break;
case hexadecimal:
break;
case decimal:
break;
}
return;
}
void f_binary(char value[/url], int b_null){
printf("(;゜д゜)ァ....\n");
}
こんな感じです。
Re:入力関数について
Posted: 2007年4月04日(水) 14:35
by miyaza
最初に1番を選んだ場合
gets()で入力された文字が'1'か'0'だけであるかを調べてそうであるなら(;゜д゜)ァ....を表示ということでよろしいのでしょうか。
こちらでは表示されましたが、どのような不具合が出るのでしょうか?
gets()での入力もできましたが・・・
Re:入力関数について
Posted: 2007年4月04日(水) 16:01
by 大工
>最初に1番を選んだ場合
gets()で入力された文字が'1'か'0'だけであるかを調べてそうであるなら(;゜д゜)ァ....を表示ということでよろしいのでしょうか。
現時点では不完全ですがそのような感じです。(ですが文字ではなく文字列です)
>こちらでは表示されましたが、どのような不具合が出るのでしょうか?
gets()での入力もできましたが・・・
getsでの入力ができなかったんです><;
実行してみると>>>>
Please choose the following
binary scale : 1
octal scale : 2
hexadecimal scale : 3
decimal scale : 4
Please input >>>1
check == 0, cnt == 0
(;゜д゜)ァ....
のようになり文字(列)が入力できることなく終了してしまっているのです。(getsの部分がコメントアウトしているような状況です。)
Re:入力関数について
Posted: 2007年4月05日(木) 07:37
by 組木紙織
fflush(stdin)とrewind(stdin)は標準入力に扱うと実装依存らしいです。
bccとVC両方でrewind(stdin)は扱えたので気づかなかったです。
getchar()を使うとか、gets()を二回使うなどして、読み捨ててあげれば出来と思います。
Re:入力関数について
Posted: 2007年4月05日(木) 12:17
by 大工
実装依存って・・・?
Re:入力関数について
Posted: 2007年4月05日(木) 17:31
by Justy
>実装依存って・
言語の仕様書に規定されていない為、環境(OSとかコンパイラとか)に
よって動作が異なることです。
>fflush(stdin)とrewind(stdin)は標準入力に扱うと実装依存らしいです。
あれ? そうでしたっけ?
確かに前者の fflush(stdin)は実装依存というか完全に規定外です。
fflushは出力ストリームか直前の操作が入力ではない更新ストリーム用なので、
入力ストリームには使えません。
(環境によっては動いてしまうかもしれませんが。)
しかし、後者の rewindはストリームならどれでもOKだったと記憶しています。
最も rewindを使う用途が「キーボードバッファをクリアしたい」のだとすると
標準入力ストリーム(stdin)がキーボードバッファとつながっているかどうかがは
環境次第なので実装依存か、とは思いますが。
Re:入力関数について
Posted: 2007年4月05日(木) 22:33
by 組木紙織
少し調べてみました。
c言語のJIS規格(JISX3010)ではfflush()は入力ストリームは未定義をしてあり、
rewind(stdin)はfseek(stdin, OL,SEEK_SET)と等価であるとして、fseekは入力ストリームと出力ストリーム
両方とも使えるとしてあるので、
上で述べたrewind()は実装依存らしいというのは間違いでした。
訂正します。不正確な情報を出してしまってすみませんでした。
Re:入力関数について
Posted: 2007年4月05日(木) 22:37
by 大工
みなさん、返信ありがとうございました。