Home > database >  Having trouble with nextLine()
Having trouble with nextLine()

Time:02-20

I am trying to build a calculator that calculates the user's scores by giving an average. If the user inputs X the calculator should stop.

Here is the problem.
Every time I enter an integer, the code first checks using inputDevice.nextLine(); causing the compiler not read the integer and to jump to the next line. This is when the Integer.parseInt(inputDevice.nextLine()) reads a new input and finally stores it. How can I change the code so the calculator reads it initially?

System.out.print("Calculates an average of all numbers entered. Enter 'x' when finished entering numbers.\n");
do {
    System.out.print("Enter a score: ");
    input = inputDevice.nextLine();
    if (input.equalsIgnoreCase("x"))
    {
        break;
    }
    else
    {
        userScore = Integer.parseInt(inputDevice.nextLine());
        userScores = userScores   userScore;
        userCount = userCount   1;
    }

CodePudding user response:

I think a lot of people forget that you're not stuck using a single Scanner, you could, for example, use one to get the input from the user and another to parse whatever was input, for example...

Scanner inputDevice = new Scanner(System.in);
System.out.print("Calculates an average of all numbers entered. Enter 'x' when finished entering numbers.\n");
int userScore = 0;
int userScores = 0;
int userCount = 0;
boolean done = false;
do {
    System.out.print("Enter a score: ");
    String input = inputDevice.nextLine();

    if (input.equalsIgnoreCase("x")) {
        done = true;
    } else {
        Scanner parser = new Scanner(input);
        if (parser.hasNextInt()) {
            userScore = parser.nextInt();
            userScores = userScores   userScore;
            userCount = userCount   1;
        }
    }
} while (!done);

The above uses a second Scanner to parse the input from the user, doing its own validation, independent of the "input scanner"

Without an additional Scanner

So, an "additional" Scanner can help you get around complex input and parsing workflows, but it's not your only option.

For example...

Scanner inputDevice = new Scanner(System.in);
System.out.print("Calculates an average of all numbers entered. Enter 'x' when finished entering numbers.\n");
int userScore = 0;
int userScores = 0;
int userCount = 0;
boolean done = false;
do {
    System.out.print("Enter a score: ");

    if (inputDevice.hasNextInt()) {
        int value = inputDevice.nextInt();
        userScore = value;
        userScores = userScores   userScore;
        userCount = userCount   1;
    } else if (inputDevice.hasNext() && "x".equalsIgnoreCase(inputDevice.next())) {
        done = true;
    } else {
        System.out.println("Invalid response");
    }
} while (!done);

What this is trying NOT to do is, use a try-catch block as a conditional flow. That is, if the input can't be parsed as a int value, what do you do? Using Integer.parseInt will throw an exception and as "general" rule of thumb, you should avoid using try-catch blocks as conditional flows

Single line, multiple inputs...

Because it was an interesting concept and oddly enough, it was a great use of a "seperate parser" Scanner. The reason been is, if we'd used just the single Scanner, it would stop at the end of the buffer in the while-loop and wait for more input, which isn't what we really want.

Scanner inputDevice = new Scanner(System.in);
System.out.print("Calculates an average of all numbers entered. Enter 'x' when finished entering numbers.\n");
int userScore = 0;
int userScores = 0;
int userCount = 0;
boolean done = false;
do {
    System.out.print("Enter a score: ");
    Scanner parser = new Scanner(inputDevice.nextLine());
    while (parser.hasNextInt()) {
        userScore = parser.nextInt();
        userScores = userScores   userScore;
        userCount = userCount   1;
    }

    if (parser.hasNext() && "x".equalsIgnoreCase(parser.next())) {
        done = true;
    }
} while (!done);
System.out.println("userScores : "   userScores);
System.out.println("userCount : "   userCount);

CodePudding user response:

I think you are trying to readLine and check if its not 'x' then consider as input(int) instead of reading twice.

Edit : Modified so user can input multiples score in one line.

Code:

------
import java.util.*;
import java.io.*;

class Read{
    public static void main(String ... $){
        int userScore =0, userScores=0, userCount=0;
        String input;
        Scanner inputDevice =new Scanner(System.in);
        PrintStream out = System.out;
        out.print("Calculates an average of all numbers entered. Enter 'x' when finished entering numbers.\n");
        boolean flag = true;

        do {
            out.print("Enter a score: ");
            input = inputDevice.nextLine();

            for(var _input : input.split(" ")){

                if (_input.equalsIgnoreCase("x")){
                    flag = false;
                    break;
                }
                else{
                    userScore = Integer.parseInt(_input);
                    userScores = userScores   userScore;
                    userCount = userCount   1;
                }
            }
        }while(flag);
        out.println("userScores : " userScores);
        out.println("userCount : " userCount);
    }
}

Output:

$ javac Read.java  && java Read
Calculates an average of all numbers entered. Enter 'x' when finished entering numbers.
Enter a score: 53 535 55
Enter a score: 53 5 222 555 22 393
Enter a score: 2
Enter a score: 3
Enter a score: x 53
userScores : 1898
userCount : 11
  •  Tags:  
  • java
  • Related