入力関数について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
大工

入力関数について

#1

投稿記事 by 大工 » 17年前

#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:入力関数について

#2

投稿記事 by 組木紙織 » 17年前

最初にscanf()したときにバッファに'\n'が残っており、その状態でgets()を使ったので'\n'のみが読み込まれ、
gets()は'\n'を'\0'に変換し、最終的にmsg[10]に入るのは'\0'だけとなるのでうまく動かないのではないかと思います。


>あと、よかったらで良いのですがscanf(" %d", &val)でa(文字)を入力したとしたら暴走しますがこれを回避するために一度文字列として入力して(getsを用いて)それをisdigitを使って判断し、それからungetcを使ってバッファにもどしscanfを使ってとりこんだほうが効率てきなのでしょうか

gets()で取り込んだならsscanf()を使ったらよいのではないかと思います。戻り値を調べれば判断できたと思います。
一度バッファに戻すとその分だけ効率が落ちるような気がするので。

大工

Re:入力関数について

#3

投稿記事 by 大工 » 17年前

返信ありがとうございます。

fflushを使ってバッファクリアしようと思ったのですがうまくいきません><;

組木紙織

Re:入力関数について

#4

投稿記事 by 組木紙織 » 17年前

fflushは出力に対して効果がある関数だったはずなので、
rewind(stdin)
を使ったらどうでしょうか?

大工

Re:入力関数について

#5

投稿記事 by 大工 » 17年前

ん~・・・それでも動いてくれません><;

miyaza

Re:入力関数について

#6

投稿記事 by miyaza » 17年前

>ん~・・・それでも動いてくれません><;
rewind()を使う場所がおかしいんじゃないですか?
まあ、ソースが無いので予想ですが。

具体的にどのように修正したかを書かないと適切な回答を得るのが難しくなると思います。

大工

Re:入力関数について

#7

投稿記事 by 大工 » 17年前

#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");
}

こんな感じです。

miyaza

Re:入力関数について

#8

投稿記事 by miyaza » 17年前

最初に1番を選んだ場合
gets()で入力された文字が'1'か'0'だけであるかを調べてそうであるなら(;゜д゜)ァ....を表示ということでよろしいのでしょうか。
こちらでは表示されましたが、どのような不具合が出るのでしょうか?
gets()での入力もできましたが・・・

大工

Re:入力関数について

#9

投稿記事 by 大工 » 17年前

>最初に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:入力関数について

#10

投稿記事 by 組木紙織 » 17年前

fflush(stdin)とrewind(stdin)は標準入力に扱うと実装依存らしいです。

bccとVC両方でrewind(stdin)は扱えたので気づかなかったです。
getchar()を使うとか、gets()を二回使うなどして、読み捨ててあげれば出来と思います。

大工

Re:入力関数について

#11

投稿記事 by 大工 » 17年前

実装依存って・・・?

Justy

Re:入力関数について

#12

投稿記事 by Justy » 17年前

>実装依存って・
 言語の仕様書に規定されていない為、環境(OSとかコンパイラとか)に
よって動作が異なることです。


>fflush(stdin)とrewind(stdin)は標準入力に扱うと実装依存らしいです。

 あれ? そうでしたっけ?

 確かに前者の fflush(stdin)は実装依存というか完全に規定外です。
 fflushは出力ストリームか直前の操作が入力ではない更新ストリーム用なので、
入力ストリームには使えません。
(環境によっては動いてしまうかもしれませんが。)


 しかし、後者の rewindはストリームならどれでもOKだったと記憶しています。

 最も rewindを使う用途が「キーボードバッファをクリアしたい」のだとすると
標準入力ストリーム(stdin)がキーボードバッファとつながっているかどうかがは
環境次第なので実装依存か、とは思いますが。

組木紙織

Re:入力関数について

#13

投稿記事 by 組木紙織 » 17年前

少し調べてみました。
c言語のJIS規格(JISX3010)ではfflush()は入力ストリームは未定義をしてあり、
rewind(stdin)はfseek(stdin, OL,SEEK_SET)と等価であるとして、fseekは入力ストリームと出力ストリーム
両方とも使えるとしてあるので、
上で述べたrewind()は実装依存らしいというのは間違いでした。

訂正します。不正確な情報を出してしまってすみませんでした。

大工

Re:入力関数について

#14

投稿記事 by 大工 » 17年前

みなさん、返信ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る