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

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

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

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

Q&A

解決済

2回答

805閲覧

C言語のgetcharを使った\nと0の判断がうまくいかない

kotarou9

総合スコア3

C

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

0グッド

0クリップ

投稿2023/04/19 07:08

実現したいこと

エンターは未入力として、0はエラーに判定されないようにしたい

数字以外、未入力の場合はエラーとしてもう一度入力できるようにするためにはどのようにすれば
良いかがわからなく行き詰ってしまったためなにかアドバイスなどいただけないでしょうか

発生している問題・エラーメッセージ

0と入力した際、未入力の判定になってしまう

該当のソースコード

int main(void) { int c; int i; int j; int num[256]; int Nmax = 0; char str; for ( i = 0; i < 10; i++) { while (1) { num[i] = 0; str = 0; while ((c = getchar()) != '\n') { if (c >= '0' && c <= '9') { num[i] = num[i]*10 + c -'0'; } else { str = c; } } if (str > 0) { num[i] = 0; } if (num[i] > 0) { break; } printf("未入力です\n"); } if (num[i] % 2 == 1) { if (num[i] > Nmax) { Nmax = num[i]; } } } if (Nmax > 0) { printf("最も大きい奇数:", Nmax); } else { printf("奇数がありませんでした\n", Nmax); } }

ブレイクの条件として
if (num[i] > 0)
{
break;
}
printf("未入力です\n");
}
上記のようにif(num[i] > 0)で条件付けしてるかだとは思うのですが
どのようにすればエンターのみ押下した場合と0だけ入力した場合の違いを判断させるかが思いつきません

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

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

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

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

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

jimbe

2023/04/19 08:06 編集

混乱してしまっているのでしたら、落ち着いて考えてください。ご自身で書いたコードを一番良く分かっているのはご自身しかいないのです。 0 も有効としたいのでしたら、なぜブレイクの条件として num[i] > 0 と 0 を抜いているのでしょうか。
kotarou9

2023/04/19 09:02

コメントありがとうございます。 最初はnum[i]に数値が代入されていれば抜けさせる(エンターのみだとループさせる)つもりで作成していましたがチェックの段階で0を入力するとエンターの時と同様に未入力のエラーに引っかかることに気づきました。
jimbe

2023/04/19 09:38 編集

>num[i]に数値が代入されていれば の「数値」に 0 が含まれることを想定されていなかったということでしょう。 今の num[i] の値の変化方法では "0" 入力と Enter のみの場合とが区別できないので、もう少し値の変化をダイナミック?にするとか、 otn さんの回答のようにフラグ変数を用いるかということになります。(「区別が付かないなら区別が付くようにする」という意味では同じことです。)
kotarou9

2023/04/21 00:29

返信遅れてしまいすみません 回答・参考のコードまでありがとうございます! おっしゃられる通り0が含まれることを想定していなかったです もう一度値の変化の区別の仕方を変えてみて作り直してみます!
guest

回答2

0

ベストアンサー

入力→変換→チェックと順に行うのも一つのテです。

c

1#include <stdio.h> 2#include <stdlib.h> //strtol 3 4int main(void) { 5 int max = 0; 6 for(int count=0; count<10; ) { 7 8 char s[32] = { 0 }; 9 for(int j=0, c; (c = getchar()) != '\n'; ) s[j++] = (char)c; //入力一行を s に貯める(改行は含まない) 10 11 char *endp; 12 int num = (int)strtol(s, &endp, 10); //s を 10 進数として数値化. 数字でない文字で止まり,そのアドレスが endp に入る 13 14 if(endp == s || *endp != 0) { //Enter だけだったら endp==s となり、数字以外が有ったら *endp!=0 となる 15 printf("未入力です\n"); 16 continue; 17 } 18 19 if(num % 2 == 1 && max < num) max = num; //奇数の最大値を更新 20 count++; //入力数カウントアップ 21 } 22 if(max > 0) { 23 printf("最も大きい奇数: %d\n", max); 24 } else { 25 printf("奇数がありませんでした\n"); 26 } 27}

投稿2023/04/19 08:49

編集2023/04/19 09:29
jimbe

総合スコア12545

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

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

0

「有効な数字入力があったかどうかフラグ」を設けるのでしょうか。

str = c;

という変数strの意味が不明ですが、そのあたりを意図した物だったのでしょうか?

あと、「123a4」のような入力の時にどうしたいかですね。これも「未入力です」にしたいのなら、数字以外が入力されたら、「有効な数字入力があったかどうかフラグ」を偽にリセットする。
「1234」という値として受け付けたいのなら、数字以外でもリセットしない。

コード例 追記

上記の、「あと、」以降がちょっとおかしかったので、訂正含めてコードを書いてみます。
numを配列にする意味が無いので、単純変数にしました。ソースはindent -nut -br -ceで整形しています。

C

1#include <stdio.h> 2 3#define VALID 1 4#define INVALID 2 5#define UNDEF 0 6 7int 8main (void) 9{ 10 int c; 11 int i; 12 int num; 13 int Nmax = 0; 14 int is_number; 15 16 for(i = 0; i < 10; i++) { 17 while(1) { 18 num = 0; 19 is_number = UNDEF; 20 while((c = getchar ()) != '\n') { 21 if(c >= '0' && c <= '9') { 22 num = num * 10 + c - '0'; 23 if(is_number == UNDEF) { 24 is_number = VALID; 25 } 26 } else { 27 is_number = INVALID; 28 } 29 } 30 if(is_number == VALID) { 31 break; 32 } 33 printf ("未入力または数字以外です\n"); 34 } 35 if(num % 2 == 1) { 36 if(num > Nmax) { 37 Nmax = num; 38 } 39 } 40 } 41 if(Nmax > 0) { 42 printf ("最も大きい奇数: %d\n", Nmax); 43 } else { 44 printf ("奇数がありませんでした\n"); 45 } 46}

未入力とエラーでメッセージを変えたい場合は、UNDEFINVALIDかを判断します。

投稿2023/04/19 07:42

編集2023/04/19 10:15
otn

総合スコア84423

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

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

kotarou9

2023/04/19 09:08

回答ありがとうございます。 最初「123a4」のように入力した際、エラーが出るようにするつもりでしたがループせず抜けてしまったので文字が入力されたらstrに入力されてnum[i]をリセットするつもりで作成していました。 フラグとは何か調べ下記のコードが真の場合だけ通った際フラグが立ってwhileから抜けれるようにしてみたのですがエンターだけ押して未入力とはならずループから抜けてしまいました while ((c = getchar()) != '\n') { if (c >= '0' && c <= '9' ) { num[i] = num[i]*10 + c -'0'; } else { str
otn

2023/04/19 10:08

コードが途中で切れてますよ。 > 「123a4」のように入力した際、エラーが出るようにするつもりで 回答に書いた「「有効な数字入力があったかどうかフラグ」を偽にリセットする。」は間違ってました。 1文字ずつ入力しながら判断する方法だと、 ・有効な数字だけが入力されている ・数字以外が1文字でも入力された ・どちらかまだ未確定 の3値要りますね。 間違ったお詫びにコードを追記しておきます。 jimbeさんの回答のように、1行入力と行の中を見るのを分けると、ロジックがシンプルで、フラグも要りません。その代わりに1行文を溜めておく文字配列が要ります。
kotarou9

2023/04/21 00:42

コードの切れと返信が遅れてしまい失礼しました 回答・コードまでありがとうございます! 3つの値がいることを曖昧に捉えていたのでわかりやすく解説していただいて納得することができました もう一度自身でコードを作ってみます! つたない質問の中で意を汲み取って回答いただけているだけで大変助かっています
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問