質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
char

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

Q&A

解決済

4回答

3576閲覧

for文による連続scanf(%c)で空の引数がそのままループしてしまう

shiki_willow

総合スコア6

char

charは文字データ型を指します。一文字分の文字コードの格納を想定としている型です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

for

for文は、様々なプログラミング言語で使われている制御構造です。for文に定義している条件から外れるまで、for文内の命令文を繰り返し実行します。

ループ

ループとは、プログラミングにおいて、条件に合致している間、複数回繰り返し実行される箇所や、その制御構造を指します

0グッド

0クリップ

投稿2019/10/22 03:20

連続して一文字を入力。数字以外を入力するとエラーメッセージを表示し、次の入力に移行する。Eを入力すると終了。それまで出てきた数字らのSumとAverageを出力。

for文でscanfで連続入力するシステムです。if文でEとそれ以外の文字、次のifで数字かそれ以外と分けました。elseに"Illegal input:"を表示するところがあるのですが、入力し判別されたあとに、常に"Illegal input:が表示されてしまいます。引数の状態を調べたところ、判別されたあとに空の引数になって、もう一度if文に入っていました。調べてもどうしてなのかわかりません。

現状の表示*Linaxのgccで実行。引数aの状態をprintfで表示している。

5 a=5 a= Illegal input: t a=t Illegal input:t a= Illegal input: 3 a=3 a= Illegal input: E a=E Sum is:8.000000 Average is:4.000000

該当のソースコード

C

1#include <stdio.h> 2#include <stdlib.h> 3 4int average = 0; 5float count = 0; 6 7void judge(char x) 8{ 9 if(x!='E'){ 10 if(x=='1'){ 11 average += 1; 12 count += 1; 13 }else if(x=='2'){ 14 average += 2; 15 count += 1; 16 . 17 . 18 . 19 }else if(x=='9'){ 20 average += 9; 21 count += 1; 22 }else{ 23 printf("Illegal input:%c\n", x); 24 } 25 } 26} 27 28int main() 29{ 30 char a; 31 int i; 32 for (i=0;a!='E';i++){ 33 scanf("%c", &a); 34 printf("a=%c\n", a); 35 judge(a); 36 } 37 printf("Sum is:%d\n", average); 38 printf("Average is:%f\n",average/count); 39 return 0; 40}

試したこと

int main(void)にしてみた → 変わらず
scanf(%*c%c)にしてみた → 変わらず
if(a!='E' && a!=' ')にしてみた → 変わらず
judge()にreturn → 変わらず

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

%cは改行コードも読み込み対象なので、そのままでは変数aに改行コードが渡されて意図しない処理となってしまいます。
%cの手前に半角スペースを1個入れてください。空白と改行コードを無視するようになります。
scanf(" %c", &a);

あと、ご質問のコードでは変数'a'が初期化されないままfor文の条件判定で使われています。char a = 0;のように必ず初期化してください。

投稿2019/10/22 06:05

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiki_willow

2019/10/23 16:38

丁寧なご説明ありがとうございます。勉強になりました。
guest

0

3 Enterの入力で、最初のscanf("%c", &a);では'3'が取得されますが、次のscanf("%c", &a);では、改行の'\n'が取得されます。
'\n'judgeに渡すと、printf("Illegal input:%c\n", x);に行きます。

isspace(a)が真の時は、何もせずに繰り返すといいでしょう。

投稿2019/10/22 04:28

otn

総合スコア84491

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shiki_willow

2019/10/23 16:41

\nが取得されることを授業で言われたような気がします。ご説明ありがとうございます。
guest

0

scanf の "%c" を " %c" に変えてみてください。
% の前にスペースを置くということです。
どうなりますか?
なぜそうなるか分かりますか?

それから、変数 a が未初期化のまま 'E' と比較されています。
また、変数 i が無意味になっています。

投稿2019/10/22 06:05

編集2019/10/22 06:08
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

scanfというのは、Enter押して初めて解釈が行われますんで、あなたの期待するような動作にはならないかと。

投稿2019/10/22 03:26

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuma-s

2019/10/22 05:38

scanf の %c に Enter を特別扱いする機能はありません。 キーボード入力の場合 Enter を押すまでプログラムに文字が 渡されないのは、キーボードドライバ(端末ドライバ)が 行バッファリングを行っているからです。 Linux あるいは、Windows で Cygwin を使っているなら、mainの 最初で system("stty cbreak"); を実行し、main の終了直前に system("stty -cbreak"); を実行して、端末ドライバにバッファ リングをやめさせれば、Enter にかかわらず、入力文字が 1文字 ずつプログラムに渡されます。
y_waiwai

2019/10/22 05:44

そう、特別扱いしないからこそ、%cにリターンコードが入って返され、期待するような動作にはなりません 提示のコードには、バッファリングを無効にしてる様子もないですしね
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問