Receive two identical applications?

In my validation method I want it to print an error message, if the user enters letters instead of a decimal value, the method does exactly what it prints the error message to the console, but it prints it twice, for example if I enter "dfdff" instead of a decimal copy: "Error, invalid number. Please try again"

"Error, invalid number. Please try again"

How do I get it to print an error message once every time the user enters a wrong value ???

 public static double getVaildSubtotal(Scanner sc)
{

    double subtotal = 0.0;
    boolean isValid = false;
    while (isValid == false)
    {
       if (sc.hasNextDouble())
       {
           subtotal = sc.nextDouble();
           isValid = true;
       }
       else
       {
           System.out.println("Error! Invalid decimal value. Try again.");
       }
       sc.nextLine();

       if (isValid == true && subtotal <= 0)
       {
           System.out.println("Error! Number must be greater then 0.");
           isValid = false;
       }
       else if (isValid == true && subtotal >= 10000)
       {
          System.out.println("Error! Number must be less then 10000.");
           isValid = false; 
       }

    }

    return subtotal;
}

      

+3


source to share


3 answers


This is probably because the Scanner

class method nextDouble()

does not "eat" the newline. This can cause the method to nextLine()

return an empty string before proceeding to the next line after reading the primitive with nextDouble()

similar methods.

This can lead to some tricky results, but the simplest way is to force the Scanner

handling of the newline explicitly by adding an extra here nextLine()

:

if (sc.hasNextDouble()) {
    subtotal = sc.nextDouble();
    sc.nextLine();
    isValid = true;
}

      

Beware that this can lead to unexpected results when the scanner separator does not just match new lines. In this case, you may accidentally miss multiple entries. Since you usually want to split on new lines, you can create a more permanent solution anyway by changing the scanner separator when you create it, for example:



Scanner sc = new Scanner(System.in);
sc.useDelimiter("[\r\n]+");

      

By using this solution, you will no longer need to use additional calls nextLine()

, because any additional newlines will be ignored. However, this system will also fail to respond to empty line inputs that would simply be skipped with this separator. If you want those to be processed, you can use an additional fix nextLine()

along with this separator for safety:

sc.useDelimiter("\r\n|[\r\n]");

      

+1


source


I have just started working with Java now, so be careful.

In a little applet I was writing for a class, I went into something like this, so I adapted the principles:

public static double getVaildSubtotal(Scanner sc)
{ 
    double subtotal = 0.0;
    boolean isValid = false;
    while (isValid != true)
    {
        String stSubTotal = sc.nextLine().trim();
        int subTotalLength = stSubTotal.length();  
        boolean checkDouble = true;
        for (int k = 0; k < subTotalLength; k++)
        {
            if (Character.isDigit(stSubTotal.charAt(k)) != true)
            {
                System.out.println("Error! Invalid decimal value. Try again.");
                checkDouble = false;
            }
        }
        if (checkDouble == true)
        {
            subtotal = Double.parseDouble(stSubTotal);
            if (subtotal <= 0)
            {
                System.out.println("Error! Number must be greater then 0.");                    
            }
            else if (subtotal >= 10000)
            {
                System.out.println("Error! Number must be less then 10000.");                    
            }
            else
            {
                isValid = true;
            }
        }            
    }
    return subtotal;
}

      

In any case, you only get one error code for each entry, since the entry captures the entire line.



But, if you are not interested in rebuilding the wheel (and honestly, I won't be offended), the current problem with the code is your sc.nextLine (); Now .nextLine ()

"advances this scanner past the current line and returns the input that was skipped."

In this case, and this is just my faith, your sc.nextLine (); reads input .nextLine () as intended. So when it comes to see if there is a double inside, no, no double, just \ n.

I would suggest removing sc.nextLine (); if whitespace is definitely needed, want it to be nextLine (), I would add another local scanner for .nextLine (); in the check method.

+2


source


You need to call sc.nextLine();

twice, because after you enter any input, you press enter, which generates a new line.
 To do this, you can handle this extra newline by adding another onesc.nextLine();

0


source







All Articles