简体   繁体   中英

Why do I have to enter in the input twice before my method accepts the input?

I'm making a simple mortgage calculator and trying to validate two things through two "if-statements" before moving on to the next method. The first thing I'm checking is if the input from the scanner is an integer. If it is, I then want to check if the integer is between 1,000 and 1,000,000.

Below is the specific code:

public static Integer checkPrincipalValidation(Scanner scanner) {
        while (true) {
            if (scanner.hasNextInt()) {
                principal = parseInt(scanner.nextLine());
                if (principal >= 1_000 && principal <= 1_000_000) {
                    break;
                }
                    System.out.println(scanner.nextLine() + " is not between 1,000 and 1,000,000. Please enter correct Principal (1K - $1M):");
            }
            if (!scanner.hasNextInt()) {
                System.out.println(scanner.nextLine() + " is not a valid integer. Please enter correct Principal (Integer):");

            }
        }
        return principal;
    }

Below is the whole file if interested:


import java.util.Scanner;

import static java.lang.Float.parseFloat;
import static java.lang.Integer.parseInt;

public class Validation {
    static int principal;

    public static Integer checkPrincipalValidation(Scanner scanner) {
        while (true) {
            if (scanner.hasNextInt()) {
                principal = parseInt(scanner.nextLine());
                if (principal >= 1_000 && principal <= 1_000_000) {
                    break;
                }
                    System.out.println(scanner.nextLine() + " is not between 1,000 and 1,000,000. Please enter correct Principal (1K - $1M):");
            }
            if (!scanner.hasNextInt()) {
                System.out.println(scanner.nextLine() + " is not a valid integer. Please enter correct Principal (Integer):");

            }
        }
        return principal;
    }


    public static Float checkInterestValidation(Scanner scanner) {
        while (true) {
            if (scanner.hasNextFloat() || scanner.hasNextInt()) {
                if (scanner.hasNextInt()) {
                    return parseFloat(scanner.nextLine());
                }
                return scanner.nextFloat();
            } else {
                System.out.println(scanner.nextLine() + " is not a valid rate");
                System.out.print("Please enter correct Rate: ");
            }
        }

    }

    public static Integer checkPeriodValidation(Scanner scanner) {

        while (true) {
            if (scanner.hasNextInt()) {
                return scanner.nextInt();
            } else {
                System.out.println(scanner.nextLine() + " is not a valid period");
                System.out.print("Please enter correct Period (Years): ");
            }
        }
    }


}

When it passes through the first "if-statement", I have to enter the number twice before it goes into the second "if-statement". Why? Thank you for your time. I took a year off of coding so I'm extremely rusty and still extremely new to java, haha!

Every time you call scanner.nextLine() you must provide additional input.

Let me write comments to your method to show you the points:

public static Integer checkPrincipalValidation(Scanner scanner) {
    while (true) {
        if (scanner.hasNextInt()) {  // (1)
            principal = parseInt(scanner.nextLine());  // (2)
            if (principal >= 1_000 && principal <= 1_000_000) {
                break;
            }
            //  (3) is the next line
            System.out.println(scanner.nextLine() + " is not between 1,000 and 1,000,000. Please enter correct Principal (1K - $1M):");
        }
        if (!scanner.hasNextInt()) {  // (4)
            //  (5) is the next line
            System.out.println(scanner.nextLine() + " is not a valid integer. Please enter correct Principal (Integer):");
        }
    }
    return principal;
}

On the code line marked (1) you check whether the input contains a valid integer value.

If it is then at the code line (2) you read that value, parse it and store the value in principal .

Then, if the value for the principal is outside of the valid range, you read the next line of input at code line (3). This is not the same value as the one that you have read at code line (2) - that value was consumed and cannot be retrieved a second time!

Then at code line (4) you check again if the next value from the input is a valid integer value. If there is no valid integer value, you consume that input at code line (5).

The total effect is this:

If the user enters for example a value "1" that value passes the condition on code line (1), is read from the input and parsed into an int value at code line (2).

Since this value is not in the valid range of 1000 <= value <= 1_000_000 the code continues to line (3) where you require the user to input an additional line so that you can tell him that this new input is not between 1,000 and 1,000,000

Then the code progresses to code line (4), expecting an additional input.

To fix this mess you should rewrite your code maybe like this:

public static int checkPrincipalValidation(Scanner scanner) {
    while (true) {
        if (scanner.hasNextInt()) {
            principal = scanner.nextInt();
            if (principal >= 1_000 && principal <= 1_000_000) {
                break;
            }
            System.out.println(principal + " is not between 1,000 and 1,000,000. Please enter correct Principal (1K - $1M):");
        } else {
            System.out.println(scanner.nextLine() + " is not a valid integer. Please enter correct Principal (Integer):");
        }
    }
    return principal;
}

Note that although this code solves your immediate problem, you might later on encounter additional problems when you read the following input with scanner.nextLine() - see the answer at Scanner is skipping nextLine() after using next() or nextFoo() for more information.

The gist of that question and answers: it is surprisingly difficult to use a Scanner if your input contains mixed input (single tokens like numbers or single words on the one hand and complete lines of input on the other hand).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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