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

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

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

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

3回答

2571閲覧

はい いいえ の選択後の動作が正しく動かない

tomox

総合スコア12

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2019/08/02 02:12

前提・実現したいこと

好きな果物を選択した後に「はい」「いいえ」で再度選択するのですが
「はい」を選択すると問題なく動きますが、一度「いいえ」を選択したあとに
再び「はい」を選択すると、もう一度果物の選択が表示されてしまいます。

このような動作をしてしまう理由が分からないので教えて頂きたいです。

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

次の中から好きな果物を選んでください 1:【メロン】 2:【りんご】 3:【バナナ】 1 メロンですね 1:【はい】 2:【いいえ】 2 もう一度選択してください 1:【メロン】 2:【りんご】 3:【バナナ】 1 メロンですね 1:【はい】 2:【いいえ】 1 正しいキーを入力してください //ここから 1:【メロン】           ・ 2:【りんご】           ・ 3:【バナナ】         //ここまでが動いてしまう理由がわかりません 1 メロンですね 1:【はい】 2:【いいえ】 1 あなたの好きな果物はメロンですね

該当のソースコード

java

1public class test4 2{ 3 public static void main(String[] args) 4 { 5 System.out.println("次の中から好きな果物を選んでください"); 6 7 String fruit = name(); 8 9 System.out.println("あなたの好きな果物は" + fruit + "ですね"); 10 } 11 12 public static String name() 13 { 14 String m = "メロン"; 15 String r = "りんご"; 16 String b = "バナナ"; 17 18 System.out.println("1:【" + m + "】"); 19 System.out.println("2:【" + r + "】"); 20 System.out.println("3:【" + b + "】"); 21 int ans = new java.util.Scanner(System.in).nextInt(); 22 23 if(ans == 1){ 24 System.out.println(m + "ですね"); 25 int ans2 = Choose(); 26 if(ans2 == 1){ 27 return m; 28 }else{ 29 ng(); 30 } 31 } 32 if(ans == 2){ 33 System.out.println(r + "ですね"); 34 int ans2 = Choose(); 35 if(ans2 == 1){ 36 return r; 37 }else{ 38 ng(); 39 } 40 } 41 if(ans == 3){ 42 System.out.println(b + "ですね"); 43 int ans2 = Choose(); 44 if(ans2 == 1){ 45 return b; 46 }else{ 47 ng(); 48 } 49 }else{ 50 System.out.println("正しいキーを入力してください"); 51 return name(); 52 } 53 return name(); 54 } 55 56 public static int Choose(){ 57 System.out.println("1:【はい】"); 58 System.out.println("2:【いいえ】"); 59 int ans2 = new java.util.Scanner(System.in).nextInt(); 60 //System.out.println("もう一度選んでねorz"); 61 return ans2; 62 } 63 64 public static String ng(){ 65 System.out.println("もう一度選択してください"); 66 return name(); 67 } 68} 69

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答3

0

既に解決されてますが、今後の参考ということで回答してみます。

  • 選択肢から選ぶ
  • 「はい」で終わり
  • 「いいえ」または不正な選択肢が選ばれれば再度選択肢を表示

という仕様なので、もうちょっとシンプルに書けるかもしれません。
既定の選択肢以外はNOとする「ホワイトリスト」の考え方ですね。

その定義あたりと配列を使います。
あとtry-catchを使って「予期しない選択肢」も捕捉できそうです(特に全角文字列とか)

細かいところを言えば、変数名やメソッド名など、もう少し要件に寄せたほうがいいかもしれません。
例:name()というメソッド名をつけているが実行結果は「選択したフルーツ名」なので「フルーツを選択する」のが分かるほうがいい

java

1import java.util.HashMap; 2import java.util.Map; 3 4public class Fruit { 5 6 private static Map<Integer, String> fruitList = new HashMap<>(); 7 static { 8 fruitList.put(1, "メロン"); 9 fruitList.put(2, "りんご"); 10 fruitList.put(3, "バナナ"); 11 } 12 private static Map<Integer, String> answerList = new HashMap<>(); 13 static { 14 answerList.put(1, "はい"); 15 answerList.put(2, "いいえ"); 16 } 17 public static void main(String[] args) { 18 System.out.println("次の中から好きな果物を選んでください"); 19 20 String fruit = selectFruit(); 21 22 System.out.println("あなたの好きな果物は" + fruit + "ですね"); 23 } 24 static String selectFruit() { 25 try { 26 fruitList.forEach((selectNumber, fruitName) -> System.out.println(selectNumber+":【" + fruitName + "】")); 27 int ans = new java.util.Scanner(System.in).nextInt(); 28 if(fruitList.get(ans) == null) { 29 return selectWrongNumber(); 30 } 31 System.out.println(fruitList.get(ans) + "ですね"); 32 return finalAnswer(ans); 33 }catch(Exception e) { 34 return selectWrongNumber(); 35 } 36 } 37 static String finalAnswer(int ans) { 38 try { 39 answerList.forEach((selectNumber,answer) -> System.out.println(selectNumber+":【" + answer + "】")); 40 int fAns = new java.util.Scanner(System.in).nextInt(); 41 if(fAns == 1) { 42 return fruitList.get(ans); 43 } 44 return selectFruit(); 45 }catch(Exception e) { 46 return finalAnswer(ans); 47 } 48 } 49 static String selectWrongNumber() { 50 System.out.println("正しいキーを入力してください"); 51 return selectFruit(); 52 } 53} 54

※ざっとしか動作確認してないのでおかしいところあるかもしれませんけど・・
※思ってたより時間がかかってしまった。色々機能探りつつデバッグこまかくやりすぎたかも。

投稿2019/08/02 03:45

編集2019/08/02 04:10
m.ts10806

総合スコア80850

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

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

m.ts10806

2019/08/02 03:46

細かいですが再”帰”処理です。再起では全く意味が変わってしまう・・・。
BluOxy

2019/08/02 03:59 編集

>もうちょっとシンプルに書けるかもしれません。 ですね。 私は、シンプルに書くことについては質問で求められていなかったため、自分の回答内容では割愛していました。mts10806さんの回答ではそこが触れられており、根本を解決するという観点で丁寧な内容でしたので高評価しました。 To:tomoxさん 個人的にはコードの繰り返し部分がやはり1番気になるポイントになるので、「m」「r」「b」という個別の変数ではなく配列を覚えて使えるようになると良いです。 そうすると、ifによる分岐が3つから1つにまとまったり、変数が少なくなったりして、幸せになれると思います。
m.ts10806

2019/08/02 04:00

BluOxyさん コメントありがとうございます。 「選択肢」というところから「配列」を使うのは中々すぐには発想がいかないところではありますが、 配列を覚えると繰り返す処理とかコードをより簡単に書くことにつながるので、覚えておきたいですね。 あとデバッグ。 余談: あとで読み返したら全部どうせ再入力促すわけだしInputMismatchExceptionなんてニッチなやつじゃなくットップのExceptionで良いんじゃないかと思ったわけです。(想定の動作も確認できたし)
tomox

2019/08/02 09:39

mts10806さん 「再帰」のご指摘ありがとうございます(;'∀') 恥ずかしい。。 見本まで作成して頂いてありがとうございます! 本見ながら、ネット見ながら理解できるように頑張ります。
tomox

2019/08/02 09:42

BluOxyさん アドバイスありがとうございます。 配列を使ったコードも作ってみますね! 分からなかったまた伺いに来てしまいます。。
m.ts10806

2019/08/02 10:17

フローチャート書いてみると良いかもしません。 そうすると流れを整理できて冗長な処理も減るかもしれません。
guest

0

ベストアンサー

もし最初に3を入力して1を入力したら正しく終了しませんか?

次の中から好きな果物を選んでください 1:【メロン】 2:【りんご】 3:【バナナ】 3 バナナですね 1:【はい】 2:【いいえ】 1 あなたの好きな果物はバナナですね

下記のelseがif(ans == 3)に対して行われているため、1や2を入れたときに必ずelseの処理が実行されてしまいます。
つまり、「入力が3でなければelseの処理が実行される」というコーディングになっているということです。

java

1if(ans == 1){ 2 //~ 3} 4if(ans == 2){ 5 //~ 6} 7 8//NOTE: ansが1や2のときでもelseの処理は実行される 9if(ans == 3){ 10 //~ 11}else{ 12 //~ 13}

解決するにはif(ans == 2)if(ans == 3)の前にelseを追加してelse if(~)の形式に変更してください。
これで「入力が1や2や3でなければelseの処理が実行される」というコーディングになります。

投稿2019/08/02 02:19

編集2019/08/02 02:25
BluOxy

総合スコア2663

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

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

tomox

2019/08/02 02:33

早速の回答ありがとうございます。 ご指摘の通り下記のように変更をしてみましたが 変化はありませんでした。(処理が違っていたらすみません) else if(ans == 2){ else if(ans == 3){ 元々、どの果物を選択しても最初に「はい」と答えると 正しく動作します。 ーーーーーーーーーーーーーーーーー 次の中から好きな果物を選んでください 1:【メロン】 2:【りんご】 3:【バナナ】 1 メロンですね 1:【はい】 2:【いいえ】 1 あなたの好きな果物はメロンですね ーーーーーーーーーーーーーーーー 果物選択後に、「いいえ」を選んだ後の動作に不具合が出てしまいます。 お時間ありましたら、再度ご教示頂けると幸いです。
BluOxy

2019/08/02 02:39

なるほど。 よく見るとngやnameメソッドの戻り値でnameメソッドを呼ぶよう作られています。 これは再帰処理と言います。 ng();と書いてあるメソッドを削除し、その行を全て System.out.println("もう一度選択してください"); と置き換えれば動作するかと思います。
tomox

2019/08/02 02:47

ありがとうございます(^^)/ 無事に解決できました。 同じ処理なのでメソッドを作ったほうがコードがスッキリするかと 思ったのですが、「再起処理」なんですね(;'∀')・・(これから勉強します!!) 何度もありがとうございました!
BluOxy

2019/08/02 02:48

return name();を書くのは、elseの中だけに留めた方が良いですね。 nameメソッドの至るところでnameメソッドを呼んでしまうと、何回呼ばれるか全然分からなくなってしまいますから。
tomox

2019/08/02 02:56

アドバイスありがとうございます! 本当に始めたばかりで、質問する仕方にも迷ってるぐらいです・・ 頑張ります!!
BluOxy

2019/08/02 03:05

お節介かもしれませんが、今回の質問のような論理エラーを無くしたいのであれば、デバッガーというツールの使い方を覚えてみてください。 そうすると論理エラーに関する質問の大半はなくなるはずなので。 詳しくは「Java デバッグ」で検索してみてください。 デバッグが出来れば生産効率は2倍、3倍…否、桁倍は上がります。なので、やはりエンジニアは皆、デバッグが当たり前にできます。
tomox

2019/08/02 09:32

色々と教えて頂きありがとうございます。 「java デバック」勉強します!!
guest

0

ここがおかしいんじゃないですかねぇ

Java

1if(ans == 1){ 2 System.out.println(m + "ですね"); 3 int ans2 = Choose(); 4 if(ans2 == 1){ 5 return m; 6 }else{ 7 ng(); 8 } 9} 10 11if(ans == 2){ 12 System.out.println(r + "ですね"); 13 int ans2 = Choose(); 14 if(ans2 == 1){ 15 return r; 16 }else{ 17 ng(); 18 } 19} 20 21if(ans == 3){ 22 System.out.println(b + "ですね"); 23 int ans2 = Choose(); 24 if(ans2 == 1){ 25 return b; 26 }else{ 27 ng(); 28 } 29} else { // このelse文 30 System.out.println("正しいキーを入力してください"); 31 return name(); 32} 33

これだと3を選ばなかった時は必ず正しいキーを入力して下さいになります

やりたいことは恐らく↓なんじゃないでしょーかねぇ

Java

1if(ans == 1){ 2 System.out.println(m + "ですね"); 3 int ans2 = Choose(); 4 if(ans2 == 1){ 5 return m; 6 }else{ 7 ng(); 8 } 9 10} else if(ans == 2){ 11 System.out.println(r + "ですね"); 12 int ans2 = Choose(); 13 if(ans2 == 1){ 14 return r; 15 }else{ 16 ng(); 17 } 18 19} else if(ans == 3){ 20 System.out.println(b + "ですね"); 21 int ans2 = Choose(); 22 if(ans2 == 1){ 23 return b; 24 }else{ 25 ng(); 26 } 27 28} else { // 1,2,3以外で判定したいならこうじゃないのかな 29 System.out.println("正しいキーを入力してください"); 30 return name(); 31} 32

投稿2019/08/02 02:20

編集2019/08/02 02:24
azuapricot

総合スコア2341

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

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

tomox

2019/08/02 02:49

いつも回答ありがとうございます(^^♪ 先程、別の方にも同じご指摘を頂きましたが「再起処理」?(これから勉強する内容なので。。) ということで、動作に変化がありませんでした。 別の処理を教えて頂き解決できました! また質問沢山出るかと思いますが、これからも宜しくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問