简体   繁体   English

我不知道如何使用while循环来确保只有正确的名称才能跳出while循环

[英]I don't know how to use while loop to make sure that only correct name can jump out of while loop

Basically my program is asking the user to input a new name and the program will check if the new name matches all the requirements.基本上我的程序要求用户输入一个新名称,程序将检查新名称是否符合所有要求。

Is yes, the name should be added in the array and printed in the external file.是的,名称应该添加到数组中并打印在外部文件中。 If no, It should ask the user to input a new name.如果不是,它应该要求用户输入一个新名称。

My question is, I don't how to use a while loop to make sure that only the name can jump out of the loop.我的问题是,我不知道如何使用 while 循环来确保只有名称可以跳出循环。

I also sign my question in the main method我还在主要方法中签署了我的问题

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.");   
            }
    }

}

The elegant solution would be making your methods to be of type boolean instead of type void.优雅的解决方案是将您的方法设为 boolean 类型,而不是 void 类型。 Then, you could do然后,你可以做

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);

Notice that I put each method in a different if statement.请注意,我将每种方法放在不同的 if 语句中。 That forces the code to reach every method.这迫使代码到达每个方法。 If you don't really need to call every method if only one of them fails, you could group them up in a single if statement, or actually, at the while condition.如果只有一个方法失败,您真的不需要调用每个方法,您可以将它们组合在一个 if 语句中,或者实际上是在 while 条件下。

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

Also, you could achieve the same result if you create the boolean variable as a member of the class and then set it to false within each void method if required - although I must advice you not to do that, even if it would work that's poor code from a design standpoint.此外,如果您将 boolean 变量创建为 class 的成员,然后在需要时在每个 void 方法中将其设置为 false ,您可以获得相同的结果 - 尽管我必须建议您不要这样做,即使它的工作效果很差从设计的角度来看代码。

After all that is said, honestly, what I would do is:说了这么多,老实说,我要做的是:

  • Distinguish the methods based on what they conceptually do.根据它们在概念上的作用来区分这些方法。 You've got here methods to input a string, check duplicates, and check format.这里有输入字符串、检查重复项和检查格式的方法。 I would create one method that encompasses every format check called "checkFormat()".我将创建一种方法,该方法包含称为“checkFormat()”的每个格式检查。

  • Then, I would make as I said every method of type boolean.然后,我会按照我所说的 boolean 类型的每种方法。

My while would be:我的时间是:

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); 

UPDATE : I just realized your code is designed to use the technique I told you not to use.更新:我刚刚意识到您的代码旨在使用我告诉您不要使用的技术。 There's a variable named "valid" that you could use at your while.您可以随时使用一个名为“valid”的变量。 Although I really advice you not to do it you could instead go ahead with:虽然我真的建议你不要这样做,但你可以改为 go :

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

In your case you might want to rather use a do... while loop (it's exactly the same as a while loop, except you are guaranteed one run. Essentially you want to run the code between the do { and } while(condition) , until a certain condition is reached (as defined in your while).在您的情况下,您可能希望使用do... while循环(它与while循环完全相同,除非您保证运行一次。基本上您希望在do {} while(condition)之间运行代码, 直到达到某个条件(如您的 while 中所定义)。

So in your implementation, you would run the while loop while the string being inputted is not valid, it'll look something similar to the following:因此,在您的实现中,您将在输入的string无效时运行 while 循环,它看起来类似于以下内容:

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();
  }
}

Notice that the checkLength method returns a boolean and the result of which is applied to your flag using a logical OR.请注意,该 checkLength 方法返回一个boolean ,其结果使用逻辑 OR 应用于您的标志。

Now, you would just add the various checks as follows:现在,您只需添加各种检查,如下所示:

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

Oh just a small point on good practice:哦,关于良好实践的一点点:

  • Rather use System.lineSeparator() instead of \n when printing out newline characters.打印换行符时,请使用System.lineSeparator()而不是\n
  • Instead of using the logical OR ( || ), use the boolean function as follows:不要使用逻辑 OR ( || ),而是使用 boolean function,如下所示:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM