1

I have two do-while loops for making custom input validations. The problem is that it automatically enters in the next do-while loop. I have to put a new nextLine() after I correctly insert the name: name = scanner.nextLine();

I am aware of the "glitch" of nextInt() when the cursor stays there and you have to call nextLine() for it to continue. Source: https://www.geeksforgeeks.org/why-is-scanner-skipping-nextline-after-use-of-other-next-functions/

But this is not the case. I am clearly missing something...

String name = "";
boolean flag_name= false;
do{
    System.out.print("Name: ");
    if(scanner.hasNextInt()){
        System.out.println(scanner.nextInt() + " That's not a valid name...\n");
        scanner.nextLine();
    }else{
        name = scanner.nextLine();
        flag_name = true;
    }
}while(!flag_name);

int age = 0;
boolean good_age = false;
do {
    System.out.print("Age: ");
    if (!scanner.hasNextInt()){
        System.out.println("That's not a valid age.");
    }else if(scanner.nextInt() <= 3 || scanner.nextInt() >= 125) {
        System.out.println("You must be over 3yo.");
        scanner.nextLine();
    }else{
        age = Integer.parseInt(scanner.nextLine());
        good_age = true;
    }
}while (!good_age);

Output:

Name: mark
Age: 'mark' That's not a valid age.
Age: 
user207421
  • 305,947
  • 44
  • 307
  • 483
  • what do you mean by it automatically enters into next do while loop ? do you mean that a consecutive iteration starts ? – AppleCiderGuy Oct 20 '21 at 19:49
  • 4
    `scanner.nextInt() <= 3 || scanner.nextInt() >= 125` this is not right! if the 1st condition is false, you will do `scanner.nextInt()` ones again. instead just read it in a variable like `int val = scanner.nextInt()` and check if `val <= 3 || val >= 125` – AppleCiderGuy Oct 20 '21 at 19:51
  • 1
    can you also add how did you create this scanner ? I see a number of inconsistencies in this code. you can try reading java doc on scanner: https://docs.oracle.com/javase/8/docs/api/java/util/Scanner.html also, please refer to this example for how to read from command line: https://javarevisited.blogspot.com/2012/12/how-to-read-input-from-command-line-in-java.html#axzz79rnEsANs – AppleCiderGuy Oct 20 '21 at 20:02
  • After you correct what @AppleCiderGuy mentioned in his 2nd comment you will also come across another issue which turns up in StackOverflow probably at least once a week. [using nextLine after nextInt or similar](https://stackoverflow.com/questions/11465066/using-scanner-nextline-after-scanner-nextint) – Omar Abdel Bari Oct 20 '21 at 23:05

1 Answers1

1

I finally figured out that I already came with a messed up scanner. On the previous step I had an unattended scanner.next(); which made everything that comes after it behaving erratically.

System.out.print("Insert an option (1,2,3): ");
input = scanner.next();
// changed:
input = scanner.nextLine();

That fixed the scanner for the subsequent steps.

I also applied the logic mentioned by @AppleCiderGuy and fixed my second do-while loop.

Final code:

String name = "";
boolean flag_name= false;
do{
    System.out.print("Name: ");
    if(scanner.hasNextInt()){
        System.out.println("That's not a valid name...");
        scanner.nextLine();
    }else{
        name = scanner.nextLine();
        flag_name = true;
    }
}while(!flag_name);

int age = 0;
boolean good_age = false;
do {
    System.out.print("Age: ");
    if (!scanner.hasNextInt()) {
        System.out.println("That's not a valid age.");
        scanner.nextLine();
    }else{
        age = Integer.parseInt(scanner.nextLine());
        if(age <= 3 || age >= 125) {
            System.out.println("You must be over 3yo.");
        }else{
            good_age = true;
        }
    }
}while (!good_age);

Lessons learned:

  1. You will always need a scanner.nextLine(); for cleaning the scanner when incorrect inputs are reached. Otherwise the incorrect input will stay in the scanner and mess up the subsequent code.
  2. When you use integers, even if correctly assigned to variables, you'll also need to clean the scanner. Is easier for me to use Integer.parseInt(scanner.nextLine()); instead.
  3. Always try to evaluate variables instead of scanner.next* methods. Because the scanner will be waiting more inputs.

Thanks.

  • 1
    1. You always need it anyway, to get to the next line. 2. See (1). 3. Unnecessary. The proper rule is never to call `Scanner.nextXXX()` unless `Scanner.hasNextXXX()` has just returned true. – user207421 Oct 21 '21 at 02:29