
こんにちは。
あるプログラムを作っていると、次のような問題が起きてしまいました。
簡単なプログラムを例にして、説明したいと思います。
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
void main(void)
{
char ch;
int i;
do{
ch=getch();
putchar(toupper(ch));
}while(ch!='q');
printf("\n");
scanf("%d",&i);
}
これはgetch()関数を使い入力された文字を大文字にして画面上に出力するものです。(qが入力されるまで)
その後に、意味はありませんが変数iに整数を入力して終了する。
ここで、問題になってくるのがこのプログラムを実行して、abcdefqと入力していくと、画面上にはABCDEFQと表示されます。そして、qが入力されたことでdo文が終了して改行が行われます。次にscanfによりいったん入力待ちになります。
この時、まだ、なにも入力していないにも関わらず、最後にgetchにより入力したqが表示されてしまいます。
qを消してscanfの入力をすればいいのですが、この問題を何とか解決したと思い質問しました。
scanfの後にgetchar()を使うときはscanf入力時の'\n'に注意が必要だということはわかるのですが、上に述べたような問題はこれに似ているのでしょうか?
参考書をみたり自分でもいろいろ試してみたのですがどうもうまくいきません。
どなたか、解決策を知っていたら是非教えて下さい。
できれば、getch()とscanfがどのように作用してこのようなことが起きてしまっているのか説明して頂けたら幸いです。
お手数ですが、みなさま、よろしくお願いいたします。
No.4ベストアンサー
- 回答日時:
何か問題が正確に伝わっていなかったりするみたいですね(苦笑)
環境は Windows9X 系でしょうか。
この環境下では、getch と scanf を近いところで使うと問題が起きるんですよ。
OS が呼び出す ReadFile() が、getch() が拾ったはずのキーのキーアップイベントを、もう1度押されたと誤認するようです。
(NT系では正常に動作するそうです)
この問題は、scanf の代わりに cscanf を使うか、scanf を使う前に __flush_win95_keyup_events() を呼び出すことで回避できます。
1度試してみて下さい。
ご回答有難う御座います。
はい、環境はWindows98です。OSの問題があったのですね!!
勉強になりました。早速試してみたいと思います。
勉強中なもので、また、みかけたらご指導の程宜しくお願い致します。
また、回答してくださったみなさま、質問の際、環境について説明を書き落としてしまい申し訳ありませんでした。
No.3
- 回答日時:
こんにちは。
itohhといいます。解決策としては、ほかの方がアドバイスしているので。
>できれば、getch()とscanfがどのように作用してこのようなことが
>起きてしまっているのか説明して頂けたら幸いです。
これは、「getch()とscanf」の関係で起こっているわけではありません。
do whileループでは、ループの最後で次のループを行うかを判定します。
そのため、getch関数で「q」が入力された後にputcharで出力され、その後、
ループの終了条件を判定します。
>do{
> ch=getch(); <-「q」を入力する。
> putchar(toupper(ch)); <-「Q」を出力する。
>}while(ch!='q'); <-ループ終了条件の判定。
回答者No.1の方の方法で行うのが、スマートな方法だと思いますよ。
ご回答有難う御座いました。
まず始めに、質問が悪くてすいません。
回答して頂いたことは、理解できます。もう一度説明しますと、
doループでは後判定なので、仮にabcqと入力すると、getch()では入力した文字が画面に出力されない為、画面にはABCQと表示されてscanfの入力待ちになります。ここで、画面にQ大文字のQが表示されてしまうのは構いません。しかし、この大文字のQ以外に小文字のqが表示されてしまうのです。
この小文字のqが表示されてしまうのが気になるのです。バックスペースでこのqを消してから希望の入力値を入れることはできるのですが、できればこのqを表示したくありません。何とかならないでしょうか?
あまりうまく説明できていないかもしれません。
お手数ですが、短いプログラムなので、試していただけると幸いです。どのようなことが起こってしまか分かっていただけると思います。
申し訳ありません。
また、アドバイスがありましたら、宜しくお願い致します。
No.2
- 回答日時:
入力バッファーをクリアーするためなら、つぎの文をscanfの前に入れるとよいでしょう。
fflush(stdin);
または
rewind(stdin)
先頭に#include <stdio.h>があれば結構です。
以上。
ご回答有難う御座います。
scanfのあとにgetchar()関数を使う時には、入力バッファをクリアーする為に('\n'をクリアーする)rewind(stdin)やfflush(stdin)を使うのは分かります。
この場合はその方法用いても解決できませんでした。
すいません。なにか分かりましたら、また、宜しくお願い致します。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
数字以外が入力されたらエラー...
-
UWSCで変数をキー入力
-
プログラミングC言語について
-
配列変数を用いて平均値を求める
-
C言語(構造体)
-
scanf が無視されます
-
正負を反転させて出力するプロ...
-
VB.NETで16進数+16進数や16進...
-
*をユーザーが入力した数字の数...
-
scanf関数 バッファに残ったエ...
-
プログラミング初心者です。 Py...
-
gets関数と構造体について
-
キーボードを押すまで処理を中...
-
Eclipseコンソール表示を、リセ...
-
if文の条件にscanf関数を使うと…?
-
入力エラーの処理について。
-
プログラミングの問題です 「金...
-
コマンドプロンプトからのEOFの...
-
C言語の問題です。 標準入力 (...
-
「Aに対するBの割合」と「Aに対...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
数字以外が入力されたらエラー...
-
*をユーザーが入力した数字の数...
-
プログラミング初心者です。 Py...
-
java初心者です。入力されたの...
-
正負を反転させて出力するプロ...
-
EDITコントロールで入力できる...
-
Excel VBAで、Application.Inpu...
-
4桁の数字以外を入力したらエラ...
-
Eclipseコンソール表示を、リセ...
-
入力値が1以下、かつ数字以外の...
-
電卓の小数点
-
コマンドプロンプトからのEOFの...
-
プログラミングの問題です 「金...
-
scanf が無視されます
-
漢字のソートについて
-
scanfが2回使えない・・・?;
-
C言語について
-
Userformの入力順序をタブオー...
-
WindowsでEOF
-
ワードで文字を入力する時の変...
おすすめ情報