C言語でのswitch文の挙動について

このQ&Aのポイント
  • C言語でのswitch文の動作についてご質問です。
  • 特定の入力に対して、switch文のcase文とdefault部が両方実行されてしまう現象を調査しています。
  • また、char型からint型に変更した場合に正常に動作することも不可解です。どういった理由によるものでしょうか。
回答を見る
  • ベストアンサー

C言語 switch文について

C言語初心者です。 以下のようにC言語でプログラムを書いてみたのですが、 一つの入力に対して、対応するcase文に加えてdefault部の内容も表示されてしまいます。 (aを入力すると day before yesterday と day after tomorrowが表示されるような感じです) i,j,k などを使ってどう実行されているかを調べると、どうやら一回の入力に対して二回switch部を回っているようです。 そうにしろなぜaに対してdefaultへ飛ぶのか理解できませんが・・ また、最初の宣言をchar から int にして(caseは、case 1とかに適当に変えて)やると、正常に動くのも不可解です。 どうなっているんでしょうか・・ どなたかご教授願えると幸いです。よろしくお願いいたします。 #include <stdio.h> int main(void) { char n; int i=0,j=0,k=0; k++; while(scanf("%c",&n),n!='E'){ i++; switch(n){ case 'a': puts("day before yesterday"); break; case 'b': puts("yesterday"); break; case 'c': puts("today"); break; case 'd': puts("tomorrow"); break; default: puts("day after tomorrow"); break; j++; } } printf("%d\n",i); printf("%d\n",j); printf("%d\n",k); return 0; }

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

  • ベストアンサー
noname#208507
noname#208507
回答No.1

> そうにしろなぜaに対してdefaultへ飛ぶのか理解できませんが・・ キーボードから 'a' [Enter] の順にキーを打って入力するので、1回目のループで'a'を、2回目のループで'\n'をscanf()で受け取ってdefaultを実行してしまいます。 下のように書き換えれば、余分なループについては回避できるでしょう。 #include<stdio.h> int main(void) { char n[2]; int i=0,j=0,k=0; k++; while(scanf("%s",n),*n!='E'){ i++; switch(*n){ ...(以下略)...

MIKI_hito
質問者

お礼

ご回答ありがとうございます。 確かにご教示のとおりに書きなおしてみたら上手くいきました。 もし差支えなければ、以下の点にもう一度ご回答願えると幸いです。 intでnを宣言したらなぜ元のプログラムでうまくいくのか(Enterの'¥n'のint での扱いのせいなのでしょうか)。 よろしくお願いいたします。

その他の回答 (3)

  • ottimisto
  • ベストアンサー率72% (8/11)
回答No.4

結論から言いますと、scanf関数の仕様です。 質問者様のコードですと、 scanf関数は、エンターキーが入力された際、1文字分の文字コードをnに代入します。 この時、エンターキーコードは、バッファメモリに残ったままとなります。 2回めのエンターを押された場合、まず、1回めのエンターキーのコードがnに代入されます。 そのため、質問者様の言われる“不可解”な現象となります。 char n を int n に変更するのみの場合では、現象は変わりません。 (1回目はうまくいくけど、2回め以降はうまくいかない。) 解決策のひとつとしては、scanf("%c",&n)の、"と%cの間に半角スペースを入れてみることです。 (他にもありますが…)

MIKI_hito
質問者

お礼

お礼遅くなり申し訳ありません。 丁寧なご回答ありがとうございます。よくわかりました。 新しい解決策も、感謝です!

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

「最初の宣言」を int にしたときは scanf の書式も %c ではないはずですね. %c と, そいつや %s がどう違うのか確認してください.

MIKI_hito
質問者

お礼

ご回答ありがとうございます。 なるほど!わかった気がします。

  • wormhole
  • ベストアンサー率28% (1621/5657)
回答No.2

>(aを入力すると day before yesterday と day after tomorrowが表示されるような感じです) 「aを入力すると」と書かれていますが実際には「aを入力してエンターキーを押すと」ではないですか? もしそうであればaの他に改行('\r'か'\n')の2つが入力されてるかと思います。

MIKI_hito
質問者

お礼

ご回答ありがとうございます。 ご指摘のとおりです。 ただ、int で nを宣言してプログラムを書いた場合には問題なく実行できたのですが、 このちがいは何に起因するのでしょうか・・。 不勉強なので、int や charの基礎的なところで誤解をしているのかもしれませんが・・ もし差支えなければ、ご回答いただけると幸いです。 よろしくお願いいたします。

関連するQ&A

  • C言語のswitch文について間違っているところを教えてください

    初めに初心者ですので間違っているところは説明つきの回答をしていただければありがたいです。 今回switch文を使って 「足し算、引き算、掛け算、割り算」のプログラムを作ったつもりなのですが、intを使うと割り算の小数点が出ないしfioat文を使うとswitch文には、使えないと出るしどのようにしたら良いのか御回答よろしくお願いします。 (今は、int文でプログラムを作っているつもりです。) #include <stdio.h> void main (void) { int a,b,k; printf("どのような計算をしたいか数字を選んでください。\n"); printf(" 1.足し算 (例 a+b)\n"); printf(" 2.引き算 (例 aーb)\n"); printf(" 3.掛け算 (例 a×b)\n"); printf(" 4.割り算 (例 a÷b)\n"); printf("計算したい番号を入力してください "); scanf("%d",&k); switch (k){ case 1: printf("aを入力してください "); scanf("%d",&a); printf("bを入力してください "); scanf("%d",&b); printf("\n答えは a+b で %d です\n",a+b); break; case 2: printf("aを入力してください "); scanf("%d",&a); printf("bを入力してください "); scanf("%d",&b); printf("\n答えは aーb で %d です\n",a-b); break; case 3: printf("aを入力してください "); scanf("%d",&a); printf("bを入力してください "); scanf("%d",&b); printf("\n答えは a×b で %d です\n",a*b); break; case 4: printf("aを入力してください "); scanf("%d",&a); printf("bを入力してください "); scanf("%d",&b); printf("\n答えは a÷b で %d です\n",a/b); break; default: printf("明記してあるどれかの数字を再入力してください"); } }

  • switch文をif文に変換

    以下のプログラムをif文に書き換えるとどうなるでしょうか? if文と論理演算子を使って短く書きかえられるらしいのですが。 #include <stdio.h> main() { int no; scanf("%d",&no); switch (no){ case 1: puts("1番です。\n"); break; case 2: puts("2番です。\n"); break; case 3: puts("3番です。\n"); break; case 4: puts("4番です。\n"); break; case 5: puts("5番です。\n"); break; case 6: puts("6番です。\n"); break; default: puts("そんな学年はありません。"); break; } }

  • C言語エラー

    C言語をいじっているのですが、16行目と19行目の「型」の前に「;」がありませんと表示されます。 どこをどう改善すればいいか教えてもらえないでしょうか /*遊び半分*/ #include <stdio.h> #include <process.h> int main() { char dear; printf("ああああ\n"); printf("ああああ \n"); scanf_s("%c", &dear); switch (dear){ case 'A04': ; int main(void); { printf("ああああ\n"); int main(void); printf("あああ\n"); printf("あああ\n"); break; system("pause"); return 0; } case 'C34' : printf("\n"); break; case 'E24' : printf("\n"); break; case 'F38' : printf("\n"); break; default: printf("メッセージはありません\n"); break;} return 0;

  • cプログラム

    #include<stdio.h> /*Calc MAX of (a,b)*/ int max(int x,int y) { if(x>y) return x; else return y; } /*Calc n!*/ void fact(int n) { int i,ans; ans=1; for(i=n;i>=1;i--){ ans*=i; } printf("ans=%d\n",ans); } /*END*/ void end() { printf("Thanks\n"); exit(0); } /*Main*/ int main() { int key; int a,b,saidai; int n; while(1){ puts("\n=====Main MENU ====="); puts("1.......max(a,b)"); puts("2.......n!"); puts("9.......END\n"); printf("Input No(1,2,9)=?"); scanf("%d",&key); switch(key){ case 1: printf("Inputs:a,b?"); scanf("%d,%d",&a,&b); saidai=max(a,b); //Call max(a,b) printf("max(%d,%d)=%d\n",a,b,saidai); break; case 2: printf("Input:n?"); scanf("%d",&n); fact(n); break; case 9: end(); break; default: printf("!!!!!Miss Input_No!!!!!\n"); break; } } のプログラムなのですが、1の処理を行った場合max(a,b)の値が正しく表示されません どこを直せばいいでしょうか? return(0);

  • C言語 エラー表示 break の位置が誤っている(関数 main ) 

    #include<stdio.h> int main(void){ int n,i,j,k; char c='*'; printf("正の整数:"); scanf("%d",&n); if(n>0){ for(i=1;i<=n;i++){ printf("%d",i); for(j=1;j<=n+1-i;j++){ if(j==1){ if(i-1>0){ for(k=i-1;k>0;k--){ printf(" "); } } } printf("%c",c); } printf("\n"); } } break; return 0; } これをコンパイルすると「break の位置が誤っている(関数 main )」と表示されるのですが何でですか? 困ってます↓

  • c言語初心者です。ついに。。

    西暦月日にちを入れると何曜日かを表示できるプラグラムをつくれましたー。まだif switch do while文しかしらないけど、switch文だけでできました。でも欠点があってうるう年の1月と2月はうまくできなんです。原因わわかっていてさいごの式bに-1をしなければいけないのですがそのうるう年だけ-1という計算をどうすればできるのかが思いつきません。もし詳しい人がいたら教えてくださいーー。 #include <stdio.h> int main(void) { int y, m, l, z,v,h,q,f,x,o,j,e,a,r,b; printf("西暦何年何月か入力してください\n"); printf("西暦。:"); scanf("%d",&y); printf("何月。:"); scanf("%d",&m); printf("何日。:"); scanf("%d",&l); z=y%400; v=y%100; h=z-v; f=h/100; switch(f) { case 3 : q=0; break; case 1 : q=4; break; case 2 : q=2; break; case 0 : q=6; break; } o=y%100; j=o/4; e=o+j; a=m; switch(a) { case 1 : r=0; break; case 2 : r=3; break; case 3 : r=3; break; case 4 : r=6; break; case 5 : r=1; break; case 6 : r=4; break; case 7 : r=6; break; case 8 : r=2; break; case 9 : r=5; break; case 10 : r=0; break; case 11 : r=3; break; case 12 : r=5; break; } b=q+e+r+l; switch (b % 7){ case 0 : puts("日曜日です。"); break; case 1 : puts("月曜日です。"); break; case 2 : puts("火曜日です。"); break; case 3 : puts("水曜日です。"); break; case 4 : puts("木曜日です。"); break; case 5 : puts("金曜日です。"); break; case 6 : puts("土曜日です。"); break; } return (0); }

  • C言語で電卓を作成する。

    C言語を用いて三項まで計算できる電卓を作りたいのですが、どうも上手くいきません。 四則演算(+、-、×、÷)の優先順位を用いたプログラミング方法が分かりません。 以下に自分で作成したソースを添付します。 このソースに修正や追加して3項までの四則演算できるプログラミングを教えていただけますか? 宜しくお願いします。 #include <stdio.h> int main(void) { int answer; /*答え*/ int x,y,z; /*x=第一項,y=第二項,第三項*/ char op1,op2; /*演算子1、演算子2*/ while(1){ printf("式を入力してください\n"); printf("式:"); scanf("%d %c %d %c %d" ,&x,&op1,&y,&op2,&z); if((op1=='+'|'-'|'*'|'/') && (op2=='+'|'-'|'*'|'/')){ switch(op2){ case '+': answer=y+z; break; case '-': answer=y-z; break; case '*': answer=y*z; break; case '/': if(z==0){ printf("ERROR\n"); return 0; } answer=y/z; break; default: printf("ERROR\n"); return 0; } switch(op1){ case '+': answer=x+answer; break; case '-': answer=x-answer; break; case '*': answer=x*answer; break; case '/': if(y==0){ printf("ERROR\n"); return 0; } answer=x/answer; break; default: printf("ERROR\n"); return 0; } printf("答え:%d\n",answer); } else { switch(op1){ case '+': answer=x+y; break; case '-': answer=x-y; break; case '*': answer=x*y; break; case '/': if(y==0){ printf("ERROR\n"); return 0; } answer=x/y; break; default: printf("ERROR\n"); return 0; } printf("答え:%d\n",answer); } } } 左辺に×、÷が来ても優先的に計算されません。

  • 【C初心者】+,-,*./について【電卓】

    【C初心者】+,-,*./について【電卓】 次のようなプログラミングを作りました。 きちんと実行できるのですが見ての通りややこしいプログラムになってます #include <stdio.h> int main(void) { int ope; double n2,n3; printf("整数1:"); scanf("%lf",&n2); puts("ADD=0,SUB=1,MUL=2,DIV=3");scanf("%d",&ope); printf("整数2:"); scanf("%lf",&n3); switch (ope) { case 0 : printf("計算すると%fになります.?n",n2+n3); break; case 1 : printf("計算すると%fになります.?n",n2-n3); break; case 2 : printf("計算すると%fになります.?n",n2*n3); break; case 3 : printf("計算すると%fになります.?n",n2/n3); break; default: printf("計算出来ません.?n"); break; } return (0); } printf文をcaseの中で5回も使っています 私としては(以下適当です、すいません) case 0 : sign= + ;break; case 1 : sign= - ・ ・ ・ default : 計算できません error=1 ;break; if (error != 0) printf("計算すると%fになります.?n",n2 sign n3); みたいな感じを想像しているのですが signはintとかcharのどれにしたらよくて signに"+"をいれて計算させるにはどうしたらいいんでしょう

  • C言語の問題

    以下はC言語の問題です。お教えください。 1000以下の素数を求めるプログラム prog.c を作成せよ。各素数を整数4桁で出力し、15個の素数を出力した時点で改行処理 を行うこと。作成したプログラムを提出せよ。 です。 僕の考えでは、 #include <stdio.h> #include <math.h> main(){ int i; int j; int ix; int k; printf("正の整数を入力して下さい: "); scanf("%d",&i); ix=(int)(sqrt((double)i)); k=0; for(j=2;j<=ix;j++) { if(i%j==0) { k=1; } } if(k==0) { printf("%d は素数です\n",i); } else { printf("%d は素数ではありません\n",i); } となると思うのですが。どうやら違うようです。全然わからないので、正しい答えを教えてください。

  • C言語、成績は4194432?

    いつも大変お世話になり誠にありがとうございます。 標記の件。 おかしな実行結果になりました。 どうしてでしょうか? ご回答の程宜しくお願い申し上げます。       記 コード #include <stdio.h> int main(void) { int res; printf("成績を入力してください。\n"); scanf("%d", &res); printf("成績は%dです。\n", res); switch(res){ case 1: printf("もっとがんばりましょう。\n"); break; case 2: printf("もう少しがんばりましょう。\n"); break; case 3: printf("さらに上をめざしましょう。\n"); break; case 4: printf("たいへんよくできました。\n"); break; case 5: printf("たいへん優秀です。\n"); break; } return 0; } 実行結果 C:\MinGW>test20.exe 成績を入力してください。 A 成績は4194432です。 C:\MinGW>test20.exe 成績を入力してください。 b 成績は4194432です。 C:\MinGW>test20.exe 成績を入力してください。 v 成績は4194432です。 度々申し訳ございません。 ご回答の程宜しくお願い申し上げます。

専門家に質問してみよう