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

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

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

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

Q&A

解決済

1回答

784閲覧

c言語でgetcharを使った未入力エラーが表示されるようにしたい

kotarou9

総合スコア3

C

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

0グッド

0クリップ

投稿2023/04/17 04:55

実現したいこと

getcharを使ってエンターのみが入力されたらエラーとして再度入力できるようにしたい

前提

1週間ほど前からC言語の勉強を始めまして
現在getcharを使って10回文字列を入力し最も大きい文字列を表示するという問題を解いているのですが
getcharで入力されたものを二次元配列に代入するところまでは分かったのですがif関数なども使ってみたのですが思ったように動作せず未入力(エンターのみ押下した場合)にエラー表示をするためにはどうすればよいかがわからないためご教授願えないでしょうか

該当のソースコード

ソースコード #include <stdio.h> #include <string.h> void main( void ) { char moji; int i,j; char str[10][256]; char max[256]; for ( i = 0; i < 10; i++) { j = 0; while ((moji = getchar()) != '\n') { if (moji == '\n') { printf("未入力再度入力してください\n"); } else { str[i][j++] = moji; break; } } str[i][j] = '\0'; } strcpy(max, str[0]); for ( i = 0; i < 10; i++) { if( strcmp(max,str[i]) < 0 ) { strcpy(max,str[i]); } } printf("%sです", max); }

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

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

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

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

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

jimbe

2023/04/17 05:20

エンターのみが入力された時、どの行でどの変数がどのような値になる(なっている)のか、分かっていますか?
kotarou9

2023/04/17 05:33

エンターのみの場合であれば15行目のmojiに\nが代入され while ((moji = getchar()) != '\n') 25行目のstr[i][0]に\nが格納されるという認識でいます str[i][j++] = moji;
guest

回答1

0

ベストアンサー

while ((moji = getchar()) != '\n')

と、mojiが改行でない時だけループの中を実行するので、
ループの中でif (moji == '\n')の条件が真となることは絶対ありません。

ループを抜けた後で、「何もstr[i]に格納されていない」<=>「j==0」を判断すれば良いかと。
「再度入力」ということなので、同じiでもう一度やり直す必要もあります。
breakも変ですね。何故1文字格納しただけでループから抜けようとするのか?

投稿2023/04/17 05:19

編集2023/04/17 05:22
otn

総合スコア84499

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

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

kotarou9

2023/04/17 08:15

ありがとうございます! breakもご指摘の通り1文字で抜けてしまいますね気づいていませんでした 同じ[i]でやり直す場合はcontinueでしょうか? この場合のcontinue文を使う場合はwhileではなくforに戻る認識であってますでしょうか?
otn

2023/04/17 08:48

> 同じ[i]でやり直す場合はcontinueでしょうか? continueは、「今の繰り返しをもう一度」じゃなくて「次の繰り返しに進む」なので、iが1つ進みます。 --i; してから continue; するという技もありますが、forのカウンターをfor()の第3項以外で操作するのはわかりにくいという考え方もあります。(言語によってはfor文の文法が違っていてそういう操作が不可能な場合も) > この場合のcontinue文を使う場合はwhileではなくforに戻る認識であってますでしょうか? continueはwhileループの外に書くので、forに対してのcontinueになります。 --i; continue; を避けるとすると、 もう一つループを作ることになりますね。 for ( i = 0; i < 10; i++) { while(1) // 無限ループ { j = 0; while ((moji = getchar()) != '\n') { str[i][j++] = moji; } if (j>0) { break; // 1文字以上あったら無限ループの途中で抜ける } printf("未入力再度入力してください\n"); } str[i][j] = '\0'; } getchar()使用が必須で無ければ、fgetsを使うと全体的にすっきりします。
kotarou9

2023/04/17 09:12

わかりやすい解説までしていただきありがとうございます 今回は[i--]で以下のもので試してみると無事動作しました ほかの言語も使うのであれ今回のコードでは動かないこともあるんですね もう一つのループでも作れるように勉強していきます 今回はお題がgetchar()だったためなるべく進捗に沿ったものだけで作成していました まだfgetsは試したことがないのでそちらも勉強させていただきます int main(void) { char moji; int i,j; char str[10][256]; char max[256]; for ( i = 0; i < 10; i++) { j = 0; while ((moji = getchar()) != '\n') { str[i][j++] = moji; } if (j < 1) { printf("未入力再度入力して下さい\n"); str[i--][j]; continue; } str[i][j] = '\0'; } strcpy(max, str[0]); for ( i = 0; i < 10; i++) { if( strcmp(max,str[i]) < 0 ) { strcpy(max,str[i]); } } printf("最も大きい文字列は%s", max); }
otn

2023/04/17 09:18

> str[i--][j]; はstrの指定要素の値を取り出して捨てているので、 i--; に書き換えても動作は同じです。 コンパイラが最適化すれば同じになると思いますが、意味的には str[i--][j]; は間違いです。
jimbe

2023/04/17 09:38

ついでに、「二次元配列に代入する」必要は無いことにも気付けると良いかとおもいます。
otn

2023/04/17 10:04

まあ、他に指摘しなかったこととしては、256文字以上入力されたらどうするんだとか、mainの返り値はintとか。
kotarou9

2023/04/17 11:51

jimbeさん、otnさん ありがとうございます。 otnさん>> i--;言われてみれば確かにそうですね気を付けます。 256文字以上の入力について調べましたがオーバーフロー?しないようif(j < 1)の所にif( j < 1 && j > 20) のように代入する最大の数を決めとけば良いでしょうか? すみません返り値に関して曖昧でint main(void)の所ですよね。関数を作る際などに不適切になるなどでしょうか・・・ jimbeさん>> わざわざ2次元配列を使わなくても最初からmaxを0としてstrに格納された文字列を都度比較・コピーすれば必要なかったということでしょうか?
otn

2023/04/17 11:57

> if(j < 1)の所にif( j < 1 && j > 20)のように そこだと時すでに遅しです。 > int main(void)の所ですよね。 あ、コメントのコードでは修正済みですね。質問文ではmainの型がvoidになっていたので。
kotarou9

2023/04/17 12:14

otnさん あぁ確かに下記の時点でバッファが溢れてしまいますね・・・ すぐには思いつかないので少し考えてみます! while ((moji = getchar()) != '\n') { str[i][j++] = moji; }
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問