🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

949閲覧

複数のif、else if文のあとにくるelse内のコードが作動しません。

irm

総合スコア25

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2020/12/18 16:20

編集2020/12/18 16:23

C#の配列とストリングの練習をしています。

プログラムの内容
コンソールアプリです。
1.ユーザーがフォーマットが指定されたモデル名を入力します。
2.入力ミスがあれば、逐一メッセージを表示。(if文)
3.正しく入力されたものは、配列にためられていく。
4.ユーザーが入力を終えたら、exitを入力して終了。
5.その後、ソートされた入力内容がプリントされる

問題点
1.if, else if , else が正常に作動しない!?
★印のelse文が反応せず、配列arrのなかに入力(input)が入らないようです。
if文が複数ある場合は、else ifを使い最後にelseを使うという構文通りに書いたのですが…。
見落としがあるのか自分では見つけられません。

2.★印のif文は、ストリングが空だったら、エラー文章を表示させたいコードなのですが、String.IsNullOrEmptyやその他のstringがnullで書くと、実行時に空エンターして何をやってもクラッシュしてしまいます。

コメント:
配列をプリントアウトしたいのに、配列に書き込めないため、1.が特に問題です。
2.も以前に同じことをやってみて、クラッシュした記憶があります。

ifが複数ある場合、それぞれが独立した扱い。if, else if, elseと続く場合はセットでの流れになっているそうです。
なのですべてのif文に該当しない場合のelse文にしたく、else ifを使ってみたのですがうまくいきません…。

どなたかC#のそういったディテールが得意なかた、ヘルプお願いいたします!

static void Main(string[] args) { bool ok = true; string input; string[] arr = new string[10]; Console.WriteLine("モデル名を入力してください。終了する場合はexitを入力してください."); Console.WriteLine(); while (ok) { for (int i = 0; i < arr.Length; i++) { Console.WriteLine($"Model No. {i + 1} "); Console.Write("モデル名を入力(例. XX-123): "); input = Console.ReadLine(); input = input.Trim(); if (input.ToLower() != "exit") { //以下のif内エラーを想定 if (int.TryParse(input.Substring(0, 1), out _)) { Console.WriteLine($"ハイフンの前はアルファベットで入力してください。"); } else if (!int.TryParse(input.Substring(input.Length - 1, 1), out _)) { Console.WriteLine($"ハイフンの後は数字で入力してください。"); }               //★このString.IsNullOrEmptyや、input == nullなどstringがnullになるようなものをif()内でいろいろ試しましたが、実行中何も入力せずにエンターを押すとクラッシュしてしまいます。 else if (String.IsNullOrEmpty(input)) { Console.WriteLine($"空のままにしないでください"); } else if (int.TryParse(input.Substring(input.Length - 3, 3), out _)) { int number = int.Parse(input.Substring(input.Length - 3, 3)); if (number < 200 || number > 500) { Console.WriteLine($"番号は200から500の間で入力してください"); } } else // ★上記if, else ifの条件がすべてfalseだったのであれば、配列にユーザー入力を代入 { arr[i] = input; Console.WriteLine($"{input} が配列arrのインデックス {i} 番に入れられました。"); } } else break; // exitでfor loop終了 } ok = false; // whileの外に出る。 } Array.Sort(arr); Console.WriteLine(); Console.WriteLine("あなたが入力したモデル名は以下になります: "); for (int i = 0; i < arr.Length; i++) { if (arr[i] != null) Console.WriteLine($"* { arr[i].ToUpper()}"); // 合計10個の配列に数少なめに入力して、全てをプリントして観察したら、エレメントは配列の最後に押しつめられるみたいです。pushとかpullとか習ったような…。 } Console.ReadLine(); }

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/12/19 00:28

目的がユーザー入力の検証で、その手段として質問のコードのようにしているなら、正規表現を使うように考え直した方が良さそうです。
退会済みユーザー

退会済みユーザー

2020/12/21 03:31

質問者さん、無言になってしまいましたが、結局どのように対処しているのですか? 進展を書いてください。回答に不明点があるなら回答のコメント欄で質問してください。ギブアップしたなどでもう Q&A は不要になったということなら、それはそれで構いませんので、その旨書いてこのスレッドはクローズしてください。とにかく無言は NG です。
退会済みユーザー

退会済みユーザー

2020/12/28 03:33

ギブアップしたなどでもう Q&A は不要になったということなら、それはそれで構いませんので、その旨書いてこのスレッドはクローズしてください。無言で放置はマナー的に最悪。
irm

2020/12/28 09:52

学習者だからこそ、この書き方で作動させるように帳尻を合わせるための微細な部分の調整に時間がかかりますし、その間もほかの課題に取り組んでいてなかなか手をつけられないのですが、そんなに迷惑ですか?人には学習の最適なプロセスがありますから。 もしお忙しいようであれば、無理なさらないでください!と明記しましたので、そこまでアグレッシブにコメントが来ると困惑してしまいます。とにかく、今は大丈夫です。ありがとうございました!
退会済みユーザー

退会済みユーザー

2020/12/28 23:58

> そんなに迷惑ですか? 少なくとも私にとっては大迷惑です。 それから、ここは質問者さんの専用の Q&A サイトではなくhttps://teratail.com/help/question-tips に書いてあるように「質問と回答を通してお互いに知識や情報を交換・共有する場所」「お互いの好意の上に成り立っている助け合いの場」ということで、ここを見ている人たちのことを考えたらそういう発言はできないはずです。 > 人には学習の最適なプロセスがありますから。 それはあなたの勝手な都合にすぎません。独学で誰にも関わってないならともかく、こういうサイトで質問する以上それは通りません。
guest

回答3

0

1.if, else if , else が正常に作動しない!?
★印のelse文が反応せず、配列arrのなかに入力(input)が入らないようです。

期待するフォーマットで入力した場合は
if (int.TryParse(input.Substring(input.Length - 3, 3), out _))
の int.TryParse() は true を返しますから続く文の中で
arr[i] = input;
をする必要があります。
最後の else は期待しないフォーマット(最後に3桁の数字がないフォーマット)の場合の処理になります。

2.★印のif文は、ストリングが空だったら、エラー文章を表示させたいコー
ドなのですが、String.IsNullOrEmptyやその他のstringがnullで書くと、
実行時に空エンターして何をやってもクラッシュしてしまいます。

if (String.IsNullOrEmpty(input)
のチェック前に空ストリングでない前提の if (式) があるかからです。

C#

1if (input.ToLower() != "exit") 2// を 3if (String.IsNullOrEmpty(input)) { 4 Console.WriteLine($"空のままにしないでください"); 5 i--; 6} else if (input.ToLower() != "exit") 7// として最初にチェックしましょう。

なお、

C#

1Array.Sort(arr); 2// とした場合、配列の要素に null があればこれが前に来てしまいます。 3Array.Sort(arr, (lhs, rhs) => { return String.IsNullOrEmpty(lhs) ? 1 : lhs.CompareTo(rhs); }); 4// 等で null を後ろにした方が気持ちいいと思います。

投稿2020/12/18 20:48

lehshell

総合スコア1156

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

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

irm

2020/12/19 09:12

早速の回答ありがとうございます。確かに、ifの条件を内容からみた時の優先順位まで考えきれていませんでした。if構文の意味上での構成で、期待するものの条件設定のなかでアクションを起こす、期待しないものではエラーメッセージという概念も新鮮です。配列のソートも参考になります。
irm

2020/12/29 00:34

今回ストリングの扱い方が盲点だったので参考になりました^^ C#が久々でいろいろやっていくうちに勘が戻ってきたところでゆっくり解決したかったのですが…。ポイントをついた回答をいただいたのでBAいうことでお知らせした置きたいと思います。またの機会がありましたらお願いいたします。ありがとうございました
Zuishin

2020/12/29 00:39 編集

> ポイントをついた回答をいただいたのでBAいうことでお知らせした置きたいと思います。 BA って何ですか?
guest

0

検証の順番と、true/false を判定した後のロジックが間違ってます。

(1) 検証の順番

空白のチェック String.IsNullOrEmpty(input) を一番最初に、次にハイフンの有無とその前後の文字列のチェック、最後にハイフンの後の数字の範囲のチェックを行う。

質問者さんのコードの順番では、空白が入力されると最初の int.TryParse(input.Substring(0, 1), out _) で例外がスローされるのでは?

(1) true/false を判定した後のロジック

検証結果 NG の場合(質問者さんのコードでは if の中の条件が true)の場合、Console.WriteLine("エラーメッセージ"); の直後に continue; 一行を追加し、その後のコードはスキップして制御を for (int i = 0; i < arr.Length; i++) に戻す。

if - else if - else に入れるのは上の (1) の判定ロジックだけで、arr[i] = input; は外す。

さらに、質問のコードはハイフンの有無とその前後の文字列のチェックが甘いです。例えば、"A12-CD3" という文字列を入力されるとどうなるか考えてみてください。また、ハイフンが無かったらどうなりますか?

ハイフンの有無とその前後の文字列のチェックは、質問のコメントに書きましたが、正規表現を使うように考え直した方が良さそうです。

投稿2020/12/19 01:35

編集2020/12/19 01:49
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

irm

2020/12/20 01:55

回答ありがとうございます。空白のチェックは他の方からもアドバイスいただきましたが、やはり最初に置くものなのですね。考えてみれば納得です。arr[i] = input;は、if - else if - else 内に入れないのですね。時間が足りず文字列チェックの甘さは自覚しています。あとごめんなさい、正規表現とはRegexを使う方法のことでしょうか?
退会済みユーザー

退会済みユーザー

2020/12/20 02:01

> 正規表現とはRegexを使う方法のことでしょうか? そうです。でも、それはとりあえず後回しにして、まずは今のコードでロジックを正しく直して実装してみてください。
退会済みユーザー

退会済みユーザー

2020/12/21 03:31

質問者さん、無言になってしまいましたが、結局どのように対処しているのですか? 進展を書いてください。回答に不明点があるなら回答のコメント欄で質問してください。ギブアップしたなどでもう Q&A は不要になったということなら、それはそれで構いませんので、その旨書いてこのスレッドはクローズしてください。とにかく無言は NG です。
irm

2020/12/21 08:11

すみません!! 気にかけていただきありがとうございます。複数のことを同時進行でしてまして、ロジックの方向性をこちらのサイトでヒントを得たところで、コードの詳細についてはまだとりかかれていません。もしお忙しいようであれば、無理なさらないでください^^
退会済みユーザー

退会済みユーザー

2020/12/22 00:08 編集

自分が関わったスレッドがオープンのままというのは気になるので、何でも良いから早急にクローズしていただきたいというお願いです。 質問者さんの事情とか都合があるのはわかりますが、こちらもいつまでも宙ぶらりんにされるのは気になります。お礼とか言ってもらう必要はないので、クローズしてください。
guest

0

自己解決

ロジック的には特に間違っていないようなので、細かな微調整のみです。使用法について指摘があったことからいったん閉じ、もしわからなくなればまた質問させていただきます。

投稿2020/12/28 09:56

irm

総合スコア25

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

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

退会済みユーザー

退会済みユーザー

2020/12/28 14:27

いえ、間違ってます。
Zuishin

2020/12/28 22:03

間違っていますね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問