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

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

ただいまの
回答率

89.20%

無限ループになってしまう Java

解決済

回答 5

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 679

YukimasaYajima

score 10

import java.util.Scanner;
public class assignment5final
{
   public static void main(String [] args){
      Scanner input = new Scanner(System.in);

      String pass = input.nextLine();

      System.out.println("password:" + pass);

      while(true){
        if(pass == "abc"){
          break; 
        }else{
          continue;
          while(true){

                int i;

                if(pass.length() < 8){
                   System.out.println(" Your password must be at least 8 characters.");
                } 

                for(i = 0; i < pass.length(); i++){
                    if(Character.isUpperCase(pass.charAt(i))){
                        break;
                    }
                }
                if(i == pass.length()){
                    System.out.println(" Your password must contain at least one uppercase letter.");
                }

                for(i = 0; i < pass.length(); i++){
                    if(Character.isLowerCase(pass.charAt(i))){
                        break;
                    }
                }
                if(i == pass.length()){
                    System.out.println(" Your password must contain at least one lowercase letter.");
                }

                for(i = 0; i < pass.length(); i++){
                    if(Character.isDigit(pass.charAt(i))){
                        break;
                    }
                }
                if(i == pass.length()){
                    System.out.println(" Your password must contain a numeber.");
                }

                if(pass.contains("password")){
                    System.out.println(" Your password cannot contain word 'password.'");
                }

                if(pass.contains(" ")){
                    System.out.println(" You password can only contain aplha numeric characters.");
                }
          }
        }
      }
   }
}

ユーザーに繰り返しインプットを要求し、特定の文字(この場合abc)が入力されたら、ループを抜け出し、プログラムを終了させたい。

最初のif文のcontinueを追加すると、それより下の文に行かなくなってしまします。ifがtrueであれば、抜け出し、ループ、インプット要求を停止させ、falseであれば、続け、それぞれのif文へと続けようと思ったのですが、思うように行きません。

while(true)を使いユーザーに続けてインプットを要求させようとしてます。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • cateye

    2019/10/10 07:16

    同上、これではコンパイルできるかどうかの確認も出来ません。

    キャンセル

  • YukimasaYajima

    2019/10/10 07:18

    修正を一度加えましたが、それでもコンパイル確認できないということですか?

    キャンセル

  • cateye

    2019/10/10 07:20

    いや、画像の時の話です。

    キャンセル

回答 5

checkベストアンサー

+2

ツッコミたいところは山ほどありますが、ひとまず下記のところが間違っていますね。

//※ここは判定式が違うよ。
//if(pass == "abc"){
if("abc".equals(pass)){
    break;
}else{
    continue;
    //これ以降意味なくねぇ
    while(true){
        //これ以降もcontinueを消した瞬間に無限ループ確定だぞ...

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/10 12:32

    Eclipseとか使っていれば、「到達不能コード」とかのコンパイルエラーが出るはずなんですがね…

    キャンセル

  • 2019/10/10 13:16

    判定式、逆転させて修正しました。
    blueJでも同じコンパイルエラー出ますねunreachable statement

    キャンセル

  • 2019/10/10 13:53 編集

    > if(String("abc").equals(pass)){
    String("abc")→new つけないとですね?^^
    あと、"abc"自体がString型なのでわざわざインスタンス化する必要はないですよね。

    あ、でも、言いたいこと、私も同じです!!

    キャンセル

  • 2019/10/11 09:37

    ああ、newはやっぱりいるのか...
    てか、インスタンス化する必要もなかったか...
    と、いう訳で修正しておきます。

    キャンセル

+2

ちょい見ですが・・・

if(pass == "abc"){

って合ってますか?
【Java入門】文字列(String)を比較する方法(「==」と「equals」)

「追記」
String pass = input.nextLine();
System.out.println("password:" + pass);
の処理は、一番外側のwhile()の内側にないとおかしいのでは?

input password? 123
password:123
 Your password must be at least 8 characters.
input password? abcd
password:abcd
 Your password must be at least 8 characters.
input password? ABCDEFGHI
password:ABCDEFGHI
 Your password must contain at least one lowercase letter.
input password? abcdefg
password:abcdefg
 Your password must be at least 8 characters.
input password? 12345678
password:12345678
 Your password must contain at least one uppercase letter.
input password? abc123ABC
password:abc123ABC

Process finished with exit code 0


「現状」

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        boolean PassOK = false;
        while (!PassOK) {
            System.out.print("input password? ");
            String pass = input.nextLine();
            System.out.println("password:" + pass);
            if (pass.equals("abc")) {
                break;
            } else {
                while(!PassOK){

                    int i;

                    if (pass.length() < 8) {
                        System.out.println(" Your password must be at least 8 characters.");
                        break;
                    }

                    for (i = 0; i < pass.length(); i++) {
                        if (Character.isUpperCase(pass.charAt(i))) {
                            break;
                        }
                    }
                    if (i == pass.length()) {
                        System.out.println(" Your password must contain at least one uppercase letter.");
                        break;
                    }

                    for (i = 0; i < pass.length(); i++) {
                        if (Character.isLowerCase(pass.charAt(i))) {
                            break;
                        }
                    }
                    if (i == pass.length()) {
                        System.out.println(" Your password must contain at least one lowercase letter.");
                        break;
                    }

                    for (i = 0; i < pass.length(); i++) {
                        if (Character.isDigit(pass.charAt(i))) {
                            break;
                        }
                    }
                    if (i == pass.length()) {
                        System.out.println(" Your password must contain a numeber.");
                        break;
                    }

                    if (pass.contains("password")) {
                        System.out.println(" Your password cannot contain word 'password.'");
                        break;
                    }

                    if (pass.contains(" ")) {
                        System.out.println(" You password can only contain aplha numeric characters.");
                        break;
                    }
                    PassOK = true;
                }
            }
        }
    }

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/10 07:47 編集

    ちょっとおかしいですがw・・・動いていますd^^
    判定NGのときに、内側のwhile()を抜ける(breakする)のが味噌です。
    で、この処理の(パスワードが正常な時)脱出条件は何でしょう?
    もし、一番下まで来たらOKなら制御構造を考え直して下さい。(do-while文を使うとか?)

    キャンセル

  • 2019/10/10 10:23 編集

    あ! while (!PassOK)は頭でも良かった ;-p

    キャンセル

+2

期待にそぐわないのは、

  • if(pass == "abc") では中身ではなく参照先の比較になっている
  • else句に入ってもcontinue;while文の頭に戻ってしまっている

から。

そもそも無限ループしたくないならwhile(true){~}とboolean直指定はすべきではないと思う。
while文で評価する条件は必ずあるのだから、それを指定すべき。

  • Javaにおける文字列の比較(「==」と「equals()」との違い)
  • continue と break

をもう少し勉強されたほうがいいと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/10 12:25

    指摘ありがとうございます。

    少しだけやりたいことの整理ができた気がします。

    ユーザインプットは繰り返し要求し続けるが、S.O.Pは一度しか表示させない(表示させる=無限ループ)
    ”ただ”、endofinputが入力された場合は、インプットのループを抜け出す。

    ユーザーインプットの”外側”にnot equal用のwhile文を起きたいのですが、できません。

    ”そもそも無限ループしたくないならwhile(true){~}とboolean直指定はすべきではないと思う。
    while文で評価する条件は必ずあるのだから、それを指定すべき”
    while文を使ったとしても、条件判断文がtrueであれば、処理に移ってしまい、無限ループになってしまうのでは無いでしょうか?

    頭の中が混乱しているので把握できてないことが有ると思うので、ミスがあれば指摘お願いします。

    キャンセル

  • 2019/10/10 14:22

    > while文を使ったとしても、条件判断文がtrueであれば、処理に移ってしまい、無限ループになってしまうのでは無いでしょうか?
    私が言いたかったのは「while(true)」←この固定の書き方がよくない、ということ。
    cateyeさんの例のように、判定結果を変数で持ち、while文内で評価されるべきということです。

    ---
    > 少しだけやりたいことの整理ができた気がします。
    きちんと整理してからプログラミングする癖をつけたほうがいいです^^;

    YukimasaYajimaさんがやりたいこと(コードから読み取れる限り)は
    ●"abc"と入力された場合はチェックせずにOKにしたい
    ●"abc"以外なら、コマンドラインからユーザが入力した値が正しい値かチェックしたい
     - チェックする内容は以下
     ・8文字未満かどうか
     ・大文字を使っているか
     ・小文字を使っているか
     ・数字を使っているか
     ・"password"という文字列を使っていないか
     ・スペースを使用していないか
    ●チェック結果が1つでも正しくなければ、何度も入力させたい

    ですかね?

    ・文字1つ1つ見るfor文がいくつもあるので、ここは1まとめにする
    ・1入力につきwhileループ1回
    ・入力された文字の内容評価はwhile文内部でチェックさせる

    を頭に入れて流れを組んでからコーディングしてみてください。

    キャンセル

  • 2019/10/10 14:23

    参考)
    サンプル付きですぐわかる!Javaでキーボード入力を読み取る方法
    https://eng-entrance.com/java-scanner-keybord

    キャンセル

  • 2019/10/10 23:17

    あの後なんとか自力で課題に沿ったコードを書くことができました。

    キャンセル

0

continue文がどういう動作をするのか理解しましょう。
ループに戻る命令なんだから、そりゃループしますぜ

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

-1

ループにたよりすぎだからじゃね

    public static void main(String[] args) throws Exception {

        String pass = null;
        try (Scanner input = new Scanner(System.in);) {

            do {
                if (pass != null) {
                    System.out.println();
                }

                System.out.print("password:");
                pass = input.nextLine();

                if (Objects.equals(pass, "abc")) {
                    break;
                }

                // 8文字未満はNG
                if (pass.length() < 8) {
                    System.out.println(" Your password must be at least 8 characters.");
                    continue;
                }

                // 英大文字のみはNG
                if (pass.matches("^[A-Z]+$")) {
                    System.out.println(" Your password must contain at least one uppercase letter.");
                    continue;
                }

                // 英小文字のみはNG
                if (pass.matches("^[a-z]+$")) {
                    System.out.println(" Your password must contain at least one lowercase letter.");
                    continue;
                }

                // 数値のみはNG
                if (pass.matches("^[0-9]+$")) {
                    System.out.println(" Your password must contain a numeber.");
                    continue;
                }

                // 英数字以外はNG
                if (!pass.matches("^[0-9A-Za-z]+$")) {
                    System.out.println(" You password can only contain aplha numeric characters.");
                    continue;
                }

                // 辞書チェック
                if (pass.contains("password")) {
                    System.out.println(" Your password cannot contain word 'password.'");
                    continue;
                }

                break;
            } while (true);
        }
    }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 89.20%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る