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

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

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

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

5回答

12734閲覧

Javaでの入力チェックのif文を減らしたい。

Kazuki_wbox

総合スコア7

Java

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

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2016/11/28 12:53

編集2016/11/28 16:16

Javaを使った簡単なプログラムを作っています。

開始

  1. 適当な文字列その1を入力してエンターキー(3文字以上10文字以下、半角数字、半角大小英字のみ)

1.1 不正な文字列の場合は再入力させる

  1. 適当な文字列その2を1.と同じ条件で入力

どちらか片方が空欄の場合は不正として再入力させる

  1. その1、2共に何も入力しない状態でエンターキーが押されるまで繰り返す

3.2 終了時には終了して良いか確認する。(y/n y:終了 n:終了しないで 1. へ戻る)
0. 『文字列その1,文字列その2』のように、csvファイル形式で出力

終了

Java

1public ArrayList<StrClass> input() { 2 3 Pattern p = Pattern.compile("^[a-zA-Z0-9]{3,11}$"); 4 Matcher m; 5 boolean is_valid_str1; 6 boolean is_valid_str2; 7 String user_input_str1; 8 String user_input_str2; 9 10 ArrayList<StrClass> strList = new ArrayList<StrClass>(); 11 12 try { 13 14 //文字列その1 入力 15 user_input_str1 = br.readLine(); 16 m = p.matcher(user_input_str1); 17 is_valid_str1 = m.matches(); 18 19 //文字列その2 入力 20 user_input_str2 = br.readLine(); 21 m = p.matcher(user_input_str2); 22 is_valid_str2 = m.matches(); 23 24 if(is_valid_str1 && is_valid_str2){ 25 StrClass strClass = new StrClass(); 26 strClass.setterStr1(user_input_str1); 27 strClass.setterStr2(user_input_str2); 28 strClass.add(strClass); 29 }else if(user_input_str1.length() != 0 && user_input_str2.length() != 0){ 30 if(!is_valid_str1 || !is_valid_str2){ 31 //エラー 文字列が不正 32 continue; 33 } 34 }else if(user_input_str1.length() == 0 && user_input_str2.length() == 0){ 35 36 boolean not_fin_flag = true; 37 38 while(not_fin_flag){ 39 //入力を終了するか確認 40 String is_input_fin = br.readLine(); 41 42 if(is_input_fin.equals("y") || is_input_fin.equals("Y")){ 43 not_fin_flag = false; 44 break; 45 }else if(is_input_fin.equals("n") || is_input_fin.equals("N")){ 46 not_fin_flag = true; 47 break; 48 }else{ 49 //エラー y/n以外の入力がされた 50 } 51 } 52 53 if(not_fin_flag){ 54 continue; 55 }else{ 56 break; 57 } 58 }else{ 59 //エラー 文字列が不正 60 continue; 61 } 62 } catch (IOException e) { 63 // TODO 自動生成された catch ブロック 64 // 例外の使い方はまだ知らないです。eclipseが怒るのでつけました。 65 e.printStackTrace(); 66 } 67 68 return strList; 69 }

###入力チェック、終了確認の段階でif文が大量発生

この継ぎ接ぎな感じをなんとかしたいと思いましたが、精一杯やってみてこれです。 正規表現「^[a-zA-Z0-9]{3,11}$」ですと入力なしの時もfind()でfalseになってしまいます。 str1とstr2の文字数が0の時に終了と判断すればいいかと思い書いてみましたが 入力エラーとなってしまったり ならばその内側に正規表現とも一致しない条件を追加して。。。 とやっていたら思い通りに動きました。 が、なんかごちゃごちゃしている気がします。 もっと頭のいい人がうまく作るとどうなるのだろうか気になり質問させて頂いております。 *私は3ヶ月ほど前にプログラミングを始めたばかりなので超基本を知らなかったり、忘れていたりします。 ぜひその辺り思い当たれば伝えていただきたいです。

###if文を減らすために
何か良い案はありませんか。
質問になっていないですが、お力を貸していただきたいです。
一応動くところまでは持ってきました。
きちんと動作することは自分で確かめることができますが、もっと良いやり方は自分よりできる方に聞かないと分かりません。。。


###補足
#等を入力させて終了させるとかそもそも別のやり方があるだろうという方もいらっしゃると思います。
その通りだと思います。良い案があれば是非教えていただきたいです。

間違った表現を修正しました。
ご指摘ありがとうございます。

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

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

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

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

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

takito

2016/11/28 13:02

1.初心者としてのご質問でしたらタイトルに初心者マークをつけておくとよいです。その方が回答する方としてもそういうつもりで言葉を選んで回答できます。2.作ったコードを掲載しましょう。処理を言葉で説明されるよりプログラムを読んだ方が理解が早いです。
swordone

2016/11/28 16:05

2と3が思いっきり矛盾している(2で空欄を許さないなら1と2がともに空欄になることはありえない)のですがそれは
guest

回答5

0

自分ならまず仕様を変えます。

  1. 妥当な文字列を連続して入力することが前提
  2. 妥当な文字列が2つ連続して入力されたらCSVへ行を追加するとともにconsoleに追加した旨を表示

連続して入力しているとどれが一つ目の入力かそのうちわからなくなるはず
3. 終了させるための特別な入力を設ける(質問にある#のようなもの)
これを設けることでy/nの確認は不要。
4. 妥当な文字列でも終了指示でもない場合は入力不正として最初からやりなおす。
一つ目の文字列を入力した後でも次の入力を間違えたらまた最初からやりなおし。そうすれば一つ目の入力を間違えていることに気づいたときにわざと2つ目を間違えて最初からやりなおすことができる。

以下コード(例外等はしょってます)

java

1static Pattern pattern = Pattern.compile(...); 2void boo(BufferedReader br, PrintWriter pr) { 3 int validCount = 0; 4 String[] ss = new String[2]; 5 String line; 6 while ((line = br.readLine()) != null) { 7 if (pattern.matcher(line).matches()) { 8 ss[validCount++] = line; 9 if (validCount == ss.length) { 10 pr.print(Arrays.stream(ss).collect(Collectors.joining(","))); // 若干おおげさ 11 pr.println(); 12 System.out.println("行を追加しました"); 13 validCount = 0; 14 } 15 } else if (line.equals("#")) { 16 break; 17 } else { 18 System.err.println("もう一度最初から英数字3~10文字または#を入力してください"); 19 validCount = 0; 20 } 21 } 22}

追記:
あるいは指示を1行単位としてもっと単純化する案もあると思います。2つのデータの間を1個以上の空白かタブで区切って1行で指示すると仮定すると以下のように単純化できます。

java

1static String elementRex = "[A-Za-z0-9]{3,10}"; 2static String lineRex = "^(" + elementRex + ")[ \t]+(" + elementRex + ")$"; 3static Pattern linePat = Pattern.compile(lineRex); 4... 5Matcher m = linePat.matcher(line); 6if (m.matches()) { 7 pr.println(m.group(1) + "," + m.group(2)); 8} else ...

なお自分の回答は仕様を変えることで論理を単純にすることに着眼しましたが、実装においてはA-pZさんが言っておられる「論理の適切な分離」がとても大切だと思います。

投稿2016/11/28 17:03

編集2016/11/29 03:49
KSwordOfHaste

総合スコア18392

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

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

0

ベストアンサー

if(not_fin_flag){
continue;
}else{
break;
}
}else{
//エラー 文字列が不正
continue;
}

whileのスコープ外にcontinue、breakがあるようなのが気になります。
見栄えより構文が間違っているのでそこのような(間違ってたらすみません)

部下が質問のようなことを言ったらとりあえずこうしてみてはと言います。

boolean hantei1 = is_valid_str1 && is_valid_str2;
boolean hantei2 = user_input_str1.length() != 0 && user_input_str2.length() != 0;
boolean hantei3 = user_input_str1.length() == 0 && user_input_str2.length() == 0;

if(hantei1){
}
else if(hantei2){
}
else if (hantei3){
}

投稿2016/11/29 01:40

tantanegg

総合スコア213

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

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

0

とりあえず気になるところとして、半角英数で3文字以上、10文字以下のチェックは

java

1^[a-zA-Z0-9]{3,10}$

でしょう。

入力チェックを実施したい部分と、終了条件になるまで繰り返す部分をわけて考え、わけた部分をメソッドや別クラスに分離するのが一番かんたんで、見やすくなるでしょう。

投稿2016/11/28 21:12

A-pZ

総合スコア12011

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

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

0

以下のようなコードのプログラムではないかと思うのですが
参考になるかも知れません
複数行用に改正しました

java

1import java.io.Console; 2import java.util.regex.Pattern; 3import java.util.regex.Matcher; 4import java.io.*; 5import java.util.*; 6 7class DGE { 8 9 public static void main(String[] args) { 10 ArrayList<String> c1 = new ArrayList<>(); 11 ArrayList<String> c2 = new ArrayList<>(); 12 13 Console co = System.console(); 14 15 String regex = "^[a-zA-Z0-9]{3,11}$"; 16 Pattern p2 = Pattern.compile(regex); 17 String s = ""; 18 19 String s2 = ""; 20 String s3 = ""; 21 outer: while (true) { 22 23 while (true) { 24 System.out.print("入力1:"); 25 s = co.readLine(); 26 27 Matcher m2 = p2.matcher(s); 28 29 if (m2.find()) { 30 31 break; 32 } 33 if (s.equals("")) 34 break; 35 36 } 37 38 while (true) { 39 System.out.print("入力2:"); 40 s2 = co.readLine(); 41 42 Matcher m2 = p2.matcher(s2); 43 44 if (m2.find()) { 45 46 break; 47 } 48 if (s2.equals("")) 49 break; 50 } 51 52 if (s.equals("") && s2.equals("")) { 53 54 while (true) { 55 System.out.print("終了確認 y/n:"); 56 s3 = co.readLine(); 57 58 if (s3.equals("y")) 59 break outer; 60 if (s3.equals("n")) 61 break; 62 63 } 64 65 } else if (s.equals("") || s2.equals("")) { 66 continue; 67 68 } else { 69 c1.add(s); 70 c2.add(s2); 71 72 } 73 74 } 75 76 try (BufferedWriter br = new BufferedWriter(new FileWriter("1.csv"))) { 77 78 for (int i = 0; i < c1.size(); i++) { 79 br.write(c1.get(i)); 80 br.write(","); 81 br.write(c2.get(i)); 82 br.newLine(); 83 84 } 85 } catch (Exception e) { 86 e.printStackTrace(); 87 } 88 89 } 90 91}

投稿2016/11/28 15:17

編集2016/11/28 17:42
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

UML で状態遷移図(ステートマシン)を書いてみて、整理してみるのはどうでしょうかね。

条件を見ると、1. が成立していたら 2. をやって、2. までできていたら 3. をチェックして……と、いくつかの状態があるように見えます。

投稿2016/11/28 15:00

tacsheaven

総合スコア13703

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問