こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

switch文とscanfについて

ソースコード-------------------------------------
#include <stdio.h>

void main(){
int i;
char s, ch;

while(1){
printf("Input 1 or 2\n");
scanf("%c", &s);

switch(s){
case '1' :
printf("Input a number\n");
scanf("%d", &i);
printf("You input '%d'\n", i);
break;
case '2' :
printf("Input a character\n");
scanf("%c", &ch);
printf("You input '%c'\n", ch);
break;
}
}
}
-----------------------------------------------

実行例-----------------------------------------
Input 1 or 2
1
Input a number
4
You input '4'
Input 1 or 2
Input 1 or 2 //------(1)
2
Input a character
You input ' //------(2)
'
Input 1 or 2
-----------------------------------------------

(1)について。
なぜ"Input 1 or 2"が二回繰り返されているのですか。

(2)について。
scanfが呼び出されて入力待ちになることを期待しているのですが、
なぜ(2)のようになってしまうのでしょうか。

投稿日時 - 2014-04-11 19:27:01

QNo.8550593

困ってます

質問者が選んだベストアンサー

char型を使いたい理由は分かりますが…
どうやら全てint型にすると解決します。
#include <stdio.h>

void main(){
int i,s,ch;



while (1){
printf("Input 1 or 2\n");

scanf("%d", &s);

switch (s){
case 1:
printf("Input a number\n");
scanf("%d", &i);
printf("You input '%d'\n", i);
break;
case 2:
printf("Input a character\n");
scanf("%d", &ch);
printf("You input '%d'\n", ch);
break;
}
}
}

投稿日時 - 2014-04-13 10:41:07

お礼

ありがとうございました。

投稿日時 - 2014-04-14 14:07:20

このQ&Aは役に立ちましたか?

3人が「このQ&Aが役に立った」と投票しています

回答(5)

補足
どうやら、scanfを呼ぶと、
sのアドレスがおかしくなってます。

投稿日時 - 2014-04-13 10:58:19

ANo.3

意図というのが一行ずつ処理したいと言うことなら、
fgetsで1行ずつ読んでみてはどうでしょう。

========================
/*エラー処理とかはほぼ省略*/
#include <stdio.h>
#include <stdlib.h>
int main(){
char buf[256];
char *end;
long num;

while(1){
printf("Input 1 or 2: ");
fgets(buf, sizeof(buf), stdin); /*bufには改行文字も含めた1行が入る*/

switch(buf[0]){
case '1' :
printf("Input a number: ");
fgets(buf, sizeof(buf), stdin);
num = strtol(buf, &end, 10);
printf("Your input '%ld'\n", num);
break;
case '2' :
printf("Input a character: ");
fgets(buf, sizeof(buf), stdin);
printf("Your input '%c'\n", buf[0]);
break;
default:
printf("Error\n");
break;
}
}
return 0;
}
=======================================
scanfは多機能なのですが、
その分挙動がわかりにくいかもしれません。
(%sで空白文字がセパレーター扱いされるとか。)

なお、scanfを使う場合の回避策は、wikipediaにも書かれてました。
他の注意点も載ってますね。
http://ja.wikipedia.org/wiki/Scanf#.E6.94.B9.E8.A1.8C.E6.96.87.E5.AD.97.E3.81.AE.E5.8F.96.E3.82.8A.E6.89.B1.E3.81.84

投稿日時 - 2014-04-13 03:25:49

お礼

ありがとうございました。

投稿日時 - 2014-04-14 14:07:32

ANo.2

Wr5

>意図したとおりに動作するようにプログラムを書き換えるとしたら

「scanf 改行」辺りで検索してみてくださいな。
http://www9.plala.or.jp/sgwr-t/c/sec05.html#s5-4-2
とか。
「scanf 改行 読み飛ばし」でも見つかるでしょう。

投稿日時 - 2014-04-11 21:19:23

ANo.1

どちらも理由は、scanfが改行文字を取得したから。

> You input ' //------(2)
> '
この結果とか分かりやすいですよね。
あなたがその手前で入力した
2
という文字列の2文字目の'\n'が出力されています。


(1)の方はswitch文のdefaultを書けば、
'1'でも'2'でもない文字(この場合'\n')が入力されていることが分かります。

投稿日時 - 2014-04-11 20:06:27

補足

意図したとおりに動作するようにプログラムを書き換えるとしたら例えばどのようになるでしょうか。
switch文は使っても使わなくても良いです。

投稿日時 - 2014-04-11 20:45:26

お礼

ありがとうございました。

投稿日時 - 2014-04-14 14:08:00