Я не знаю, как использовать цикл while, чтобы убедиться, что только правильное имя может выпрыгнуть из цикла while - PullRequest
0 голосов
/ 11 ноября 2019

В основном моя программа просит пользователя ввести новое имя, и программа проверит, соответствует ли новое имя всем требованиям.

Если да, имя должно быть добавлено в массив и напечатано ввнешний файл. Если нет, он должен попросить пользователя ввести новое имя.

Мой вопрос: я не знаю, как использовать цикл while, чтобы убедиться, что только имя может выпрыгнуть из цикла.

Я также подписываю свой вопрос в основном методе

public static void main(String[] args)throws FileNotFoundException {
    readFile();
    listUserName();
    while() {          // my question is at here that I don't how to use while loop to make 
                          //sure that only the name which pass all the check..method can 
                          //jump out of the loop
inputNewName();
            checkduplicate();
            checklength();
            checkcase();
            checkstart();
            checknumber();
            checkspecial(); 
        }
        addNewName();
        listUserName();


    }
    public static void readFile()throws FileNotFoundException {
     //read file and reseve in array
        Scanner input = new Scanner(new File("users.txt"));
        int i=0;
        while(input.hasNext()) {
               String info=input.next();
               userName[i]=info;
               i++;
        }
    }
    public static void listUserName() {//print name
        for(int i=0;i<userName.length;i++) {
            System.out.println(userName[i]);
        }       
    }
    public static void inputNewName() {// prompt uder for a new name
        System.out.println("Create a new user:");
        Scanner console=new Scanner(System.in);
        newname=console.next();
    }
    public static void addNewName()throws FileNotFoundException {//add new name in array

       System.out.println("User: \""+newname+"\" added successfully!");
       System.out.println("List of usernames: ");

       String[] tempuser=new String[userName.length+1]; 
        for(int i=0;i<(userName.length+1);i++) {
            if(i<userName.length) {
                tempuser[i]=userName[i];

            }else if(i==userName.length) {
                tempuser[userName.length] =newname;
            }
            System.out.println(tempuser[i]);
            }
            userName=tempuser;
            PrintStream out=new PrintStream(new File("users.txt"));  
            for(int i=0;i<userName.length;i++) {
                out.println(userName[i]);
            }
 }   
    public static void checkduplicate() { //check duplicate

        for(int i=0;i<userName.length;i++) {    
            if(newname.equals(userName[i])) {
                System.out.println("Invalid Name.Name already in use.");    
               }else {
                   valid=true;
               }
        }
    }
    public static void checklength() {//check length
            if(newname.length()>7) {
                System.out.println("Invalid Name"+"\n"+"Name too long.");
                }
            if(newname.length()<4) {
                System.out.println("Invalid Name"+"\n"+"Name too short.");
                }
    }
    public static void checkcase() {//check case                            
            boolean upcase=false;
            boolean lowcase=false;
            for(int i=0;i<newname.length();i++) {

                    if((0+newname.charAt(i))>=65&&(0+newname.charAt(i)<=90)) {
                        upcase=true;
                    }else if((0+newname.charAt(i))>=97&&(0+newname.charAt(i))<=122) {
                        lowcase=true;
                    }
            }
            if(upcase==false||lowcase==false) {
                System.out.println("Usernames must have lower-case and upper-case");
            }
    }   
    public static void checkstart() {
        if(((0+newname.charAt(0))<65&&(0+newname.charAt(0)>99))||
                ((0+newname.charAt(0))<97&&(0+newname.charAt(0))>122)){

                System.out.println("Invalid name. Name must start with a letter");
            }       
    }
    public static void checknumber() {
        boolean check=false;
        for(int i=0;i<newname.length();i++) {
            if((0+newname.charAt(i))>=48&&(0+newname.charAt(i))<=57) {
                check=true;
            }
        }
        if(check!=true) {
            System.out.println("Username must have at least one number");
            }
    }
    public static void checkspecial() {
        boolean check=false;
            for(int i=0;i<newname.length();i++) {
                if((0+newname.charAt(i))==33||(0+newname.charAt(i))==35||(0+newname.charAt(i))==63) {
                    check=true;
                }
            }
            if(check!=true) {
                System.out.println("Username must have at least one special character.");   
            }
    }

}

Ответы [ 2 ]

0 голосов
/ 11 ноября 2019

В вашем случае вы можете использовать цикл do ... while (он точно такой же, как цикл while, за исключением того, что вам гарантирован один цикл. По сути, вы хотите запустить код между do { и } while(condition), пока не будет достигнуто определенное условие (как определено в вашем while).

Таким образом, в вашей реализации вы выполняете цикл while, пока введенный string недопустим, он будет выглядеть как-тоаналогично следующему:

public class WhileLoop {

  public WhileLoop() {}

  public void run() {
    String name;
    boolean isValid;
    do {
        isValid = Boolean.FALSE;  // We want to set this to FALSE on each run of the loop. 
        System.out.println("Create a new user:");
        Scanner console = new Scanner(System.in);
        name = console.next();
        isValid = isValid || checklength(name); // run the checkLength method and perform a logical OR on the result from the method
    } while (!isValid); // loop while isValid = FALSE (Not TRUE)
    System.out.println("Name: " + name);
  }

  public boolean checklength(String name) { //check length, return TRUE if valid, else FALSE.
    boolean isVaild = Boolean.TRUE; // Set the default return value to FALSE
    if(name.length() > 7) {
        System.out.println("Invalid Name" + System.lineSeparator() + "Name too long.");
        isVaild = Boolean.FALSE; // If not valid then set isVaild to FALSE
    }
    return isVaild;
  }

  public static void main (String ... args) {
    WhileLoop whileLoop = new WhileLoop();
    whileLoop.run();
  }
}

Обратите внимание, что метод checkLength возвращает boolean и результат которого применяется к вашему флагу с использованием логического ИЛИ.

Теперь вы простодобавьте различные проверки следующим образом:

isValid = isValid || checklength(name);
isValid = isValid || checkCase(name);
...
isValid = isValid || checkStart(name);

О, просто небольшая отметка о хорошей практике:

  • Вместо использования \n вместо распечатки символов новой строки лучше использовать System.lineSeparator().
  • Вместо использования логического ИЛИ (||) используйте булеву функцию следующим образом:

    isValid = checklength(name); isValid = Boolean.logicalOr(isValid, checkCase(name)); ... isValid = Boolean.logicalOr(isValid, checkStart(name));

0 голосов
/ 11 ноября 2019

Элегантным решением было бы сделать ваши методы булевыми, а не void. Затем вы можете сделать

boolean light;

do{
    light = true;
    if(!inputNewName()) light=false;
    if(!checkduplicate()) light=false;
    if(!checklength()) light = false;
    if(!checkcase()) light = false;
    if(!checkstart()) light = false;
    if(!checknumber()) light = false;
    if(!checkspecial()) light = false; 
}while(light==false);

Обратите внимание, что я помещаю каждый метод в отдельную инструкцию if. Это заставляет код достигать каждого метода. Если вам на самом деле не нужно вызывать каждый метод в случае сбоя только одного из них, вы можете сгруппировать их в один оператор if или фактически при условии while.

while(!inputNewName() || !checkduplicate() || !checklength() || !checkcase() || !checkstart() || !checknumber() || !checkspecial()) {}

Кроме того, вы можетедостичь того же результата, если вы создадите логическую переменную в качестве члена класса, а затем при необходимости установите для нее значение false в каждом методе void - хотя я должен посоветовать вам не делать этого, даже если это сработает, что плохой код из проектаточка зрения.

После всего сказанного, честно говоря, я бы сделал следующее:

  • Различайте методы, основанные на том, что они концептуально делают. У вас есть здесь методы для ввода строки, проверки дубликатов и проверки формата. Я хотел бы создать один метод, который охватывает каждую проверку формата, называемый "checkFormat ()".

  • Затем я бы сделал, как я сказал, каждый метод типа логический.

Мое время было бы:

boolean light;
do
{
    light = inputNewName();
    if(light) light = checkDuplicate(); //this D should be upper case to follow the camel-case convention.
    if(light) light = checkFormat();
} while (!light); 

ОБНОВЛЕНИЕ : Я только что понял, что ваш код предназначен для использования техники, которую я сказал вам не использовать,Существует переменная с именем «valid», которую вы можете использовать в свое время. Хотя я действительно советую вам не делать этого вы могли бы вместо этого продолжить:

do{
    //all your stuff
} while(!valid);
...