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

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

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

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

コマンドライン

コマンドライン(別名:Command Line Interface)は、ユーザに命令の入力を促す(プロンプト)文字列の表示を行い、すべての操作をキーボードを用いて文字列を打ち込む事でプログラムを走らせるユーザインターフェースです。

Q&A

5回答

1169閲覧

javaで年ごとの九星を求めたい

icecleam

総合スコア46

Java

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

コマンドライン

コマンドライン(別名:Command Line Interface)は、ユーザに命令の入力を促す(プロンプト)文字列の表示を行い、すべての操作をキーボードを用いて文字列を打ち込む事でプログラムを走らせるユーザインターフェースです。

0グッド

1クリップ

投稿2020/10/05 12:15

編集2020/10/05 14:44

コマンドで引数に1つの値(西暦)を与えてその年の九星を出力するようにしたいです。
上記の仕様を以下のコードで、実装しようとしたのですが、
引数の数が1以外の時に、エラーメッセージ「コマンドライン引数の数が不正です」を出すようにしたいのですが、以下のような実行結果になってしまいます。

正常に動作させるにはどのように修正すれば良いか教えていただけないでしょうか。
よろしくお願いします

実行結果

・2000 1500と入れた時に、2000の方を読み込んで九紫火星と出てしまう。
→「コマンドライン引数の数が不正です」と出したい


現状のコード

java

1import java.util.*; 2 3public class Hoshi { 4 public static void main(String[] args) { 5 int num = 0; 6 try { 7 num = Integer.parseInt(args[0]); 8 } catch (ArrayIndexOutOfBoundsException e) { 9 System.out.println("コマンドライン引数の数が不正です"); 10 return; 11 } catch (NumberFormatException e) { 12 System.out.println("コマンドライン引数には正の整数を指定してください"); 13 return; 14 } 15 if (num < 0) { 16 System.out.println("コマンドライン引数には正の整数を指定してください"); 17 return; 18 } 19 if (num < 1600) { 20 System.out.println("コマンドライン引数は 1600 年以降を指定してください"); 21 return; 22 } 23 24 int s = 0; 25 int a = 0; 26 s = num % 9; 27 28 if(s == 0){ 29 s = 1; 30 } 31 if (s == 1){ 32 s = 10; 33 } 34 35 a = 11 - s; 36 37 String msg = null; 38 39 switch (a) { 40 case 1: 41 msg = "一白水星"; 42 break; 43 case 2: 44 msg = "二黒土星"; 45 break; 46 case 3: 47 msg = "三碧木星"; 48 break; 49 case 4: 50 msg = "四緑木星"; 51 break; 52 case 5: 53 msg = "五黄土星"; 54 break; 55 case 6: 56 msg = "六白金星"; 57 break; 58 case 7: 59 msg = "七赤金星"; 60 break; 61 case 8: 62 msg = "八白土星"; 63 break; 64 case 9: 65 msg = "九紫火星"; 66 break; 67 default: 68 } 69 70 System.out.println(msg); 71 } 72}

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

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

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

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

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

guest

回答5

0

  1. 文字列入力
  2. 入力文字列が数値かどうかをチェック
  3. そうでないならメッセージ出力し、1へ
  4. 入力文字列を数値変換し、1600以上かをチェック
  5. そうでないならメッセージ出力し、1へ
  6. 九星の出力
  7. おしまい

こういうのでどうぞ

投稿2020/10/05 12:27

y_waiwai

総合スコア88042

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

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

icecleam

2020/10/05 12:31

ご回答ありがとうございます。 すみません、上記のことはわかっているつもりなのですが 具体的なコードの書き方がわからずに、ご質問させていただきました。。
y_waiwai

2020/10/05 12:32

どの部分がわからないんでしょうか。
icecleam

2020/10/05 12:34

以下の4点で思うように動いてくれないので、この4点になります。。 ・1599を入れた際に、五黄土星と出てしまう。 →コマンドライン引数は 1600 年以降を指定してくださいと出したい ・abcと入れた際に、コマンドライン引数は 1600 年以降を指定してくださいと出てしまう →コマンドライン引数には正の整数を指定してくださいと出したい ・2007,2008と入れた時になぜか、何も表示されない(他の値でも発生する可能性あり) ・2000 1500と入れた時に、2000の方を読み込んで九紫火星と出てしまう。 →「コマンドライン引数の数が不正です」と出したい
y_waiwai

2020/10/05 12:39

入力した年が、1600以上かどうかを判定しましょう。 入力した文字列が、数値かどうかを判定しましょう あとは、あなたのコードがまずいので、作り直しましょう。
icecleam

2020/10/05 12:46

すみません、その判定の方法が調べてもわからずに、ご質問させていただいていました。。
swordone

2020/10/05 19:08

判定の方法を調べるとは?何を調べたのでしょうか?
guest

0

Java

1try { 2 num = Integer.parseInt(args[0]); 3} catch (ArrayIndexOutOfBoundsException e) { 4 System.out.println("コマンドライン引数の数が不正です"); 5 return; 6}

当然ですが、"コマンドライン引数の数が不正です"と表示されない原因はここにあるはずです。
System.out.println("コマンドライン引数の数が不正です");
が実行されれば、表示されるはずなので。

ではなぜこの部分が実行されないのか?
このコードでは、tryブロックの中でArrayIndexOutOfBoundsExceptionが発生した際にSystem.out.Printlnが実行されることになっていますね。
ArrayIndexOutOfBoundsExceptionとは何か?Oracleのドキュメントを見ると以下のように書いてあります。

不正なインデックスを使って配列がアクセスされたことを示すためにスローされます。つまり、インデックスが負または、配列のサイズ以上の場合です。

さて、tryブロックの中では、

Java

1num = Integer.parseInt(args[0]);

としていますが、コマンドライン引数を2000 1500と入れたときにこの部分でArrayIndexOutOfBoundsExceptionは発生するでしょうか。
args[0]はコマンドライン引数のひとつ目の要素を示します。配列(コマンドライン引数)に格納されている要素の数は2ですから、これは負の数でも配列サイズ以上の数でもありません。よって、ArrayIndexOutOfBoundsExceptionは発生せず、一番最初の要素2000を読み込むことになります。

原因の箇所がわかったらあとはそこを修正するだけです。
修正方法に関しては具体的なコードは書かずにヒントを出すにとどめておきます。

⓵Javaはコマンドライン引数を配列の形で受け取る。
⓶Javaには配列の要素の数を数える方法がある。

投稿2020/10/06 13:43

water_coffee

総合スコア7

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

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

0

結果出力までのエラーチェックと正常出力が1つのtry~catchで包まれてしまっているので、可読性が良くないように思えます。
エラー入力は処理本体の手前で弾くよう記述し、処理中断=メソッドの終了としてreturn;で中断させた方が書きやすいでしょう。

同じ比較のifが続きますのでswitch文で分岐するか、または列挙型(enum)をあらかじめ定義して比較する方が、よりきれいな実装になるかと思います。以下はswitch文の例です。

なお、変数 a の計算方法は下記ソースにコメントしていますが、計算式を間違えているようです。

java

1public class 九星 { 2 3 public static void main(String[] args) { 4 int num = 0; 5 try { 6 num = Integer.parseInt(args[0]); 7 } catch (ArrayIndexOutOfBoundsException e) { 8 System.out.println("コマンドライン引数の数が不正です"); 9 return; 10 } catch (NumberFormatException e) { 11 System.out.println("コマンドライン引数は 1600 年以降を指定してください"); 12 return; 13 } 14 if (num < 0) { 15 System.out.println("コマンドライン引数には正の整数を指定してください"); 16 return; 17 } 18 if (num < 1600) { 19 System.out.println("コマンドライン引数は 1600 年以降を指定してください"); 20 return; 21 } 22 23 int s = 0; 24 int a = 0; 25 s = num % 9; 26 a = 11 - s; // sの値は0~8しか取らないので、11-sはあってますか? 27 28 String msg = null; 29 30 switch (a) { 31 case 0: 32 msg = "一白水星"; 33 break; 34 case 1: 35 msg = "二黒土星"; 36 break; 37 ....(中略).... 38 default: 39 40 } 41 42 System.out.println(msg); 43 } 44}

投稿2020/10/05 14:09

A-pZ

総合スコア12011

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

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

icecleam

2020/10/05 14:37 編集

ご回答ありがとうございます 以下のコードで ・2000 1500と入れた時に、2000の方を読み込んで九紫火星と出てしまう。 →「コマンドライン引数の数が不正です」と出したい この問題以外は解決することができました。 どのように修正すれば、引数の数が2つの時にエラーメッセージを出すことができますでしょうか。。 教えて頂きたいです 現在のコード import java.util.*; public class Hoshi { public static void main(String[] args) { int num = 0; try { num = Integer.parseInt(args[0]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("コマンドライン引数の数が不正です"); return; } catch (NumberFormatException e) { System.out.println("コマンドライン引数には正の整数を指定してください"); return; } if (num < 0) { System.out.println("コマンドライン引数には正の整数を指定してください"); return; } if (num < 1600) { System.out.println("コマンドライン引数は 1600 年以降を指定してください"); return; } int s = 0; int a = 0; s = num % 9; if(s == 0){ s = 1; } if (s == 1){ s = 10; } a = 11 - s; String msg = null; switch (a) { case 1: msg = "一白水星"; break; case 2: msg = "二黒土星"; break; case 3: msg = "三碧木星"; break; case 4: msg = "四緑木星"; break; case 5: msg = "五黄土星"; break; case 6: msg = "六白金星"; break; case 7: msg = "七赤金星"; break; case 8: msg = "八白土星"; break; case 9: msg = "九紫火星"; break; default: } System.out.println(msg); } }
icecleam

2020/10/05 14:34 編集

追記 すみません、実行時の引数で2007と入れた時、やはりメッセージがnullとなってしまいました。。 ↑ 重ね重ねすみません、こちらは解決しました
momon-ga

2020/10/06 01:41

> どのように修正すれば、引数の数が2つの時にエラーメッセージを出すことができますでしょうか。 エラーで表示するメッセージの通り、”コマンドライン引数の数”を調べればよいのでは? ちなみに、引数が2個の時にエラーを出すわけじゃないですよね?(3個だとエラーにしない?)
guest

0

ほかの方の回答でほぼ出尽くしているのですが、
判定の仕方がわからないとのことなので。

  • 1600以上かどうかを判定

num >= 1600
こちらは恐らく理解されているのだと思います。

  • 入力の文字列が数値かどうかを判定

現在利用されているコードでcatchしている例外NumberFormatExceptionが
どこで、なぜthrowされるかを見てみれば答えは分かるかと思われます。

例外や利用している関数をjavadocで見てみると同じような時に
助けになるかなと思います。

投稿2020/10/05 13:02

marusa

総合スコア17

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

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

0

・1599を入れた際に、五黄土星と出てしまう。

→コマンドライン引数は 1600 年以降を指定してくださいと出したい

これに関しては以下をif文より前に持ってくる
if(0 < num && num < 1600){
System.out.println("コマンドライン引数は 1600 年以降を指定してください");
}

・abcと入れた際に、コマンドライン引数は 1600 年以降を指定してくださいと出てしまう

→コマンドライン引数には正の整数を指定してくださいと出したい

これに関してはちょっとめんどうですが、こちらを参考にするといいかも。
https://oshiete.goo.ne.jp/qa/3998172.html

・2007,2008と入れた時になぜか、何も表示されない(他の値でも発生する可能性あり)

これに関してはaがそれぞれ11と10だから。

投稿2020/10/05 12:31

firegrape

総合スコア902

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問