infinite loop in a while statement - java

import java.util.Scanner;
public class Main {
public static void main(String[] args) {
System.out.println("\nThe sum of the numbers is: " + getSumOfInput());
}
public static int getSumOfInput () {
int counter = 0;
int sumOfNums = 0;
Scanner userInput = new Scanner(System.in);
while(counter <= 10) {
System.out.print("Enter the number " + counter + ": ");
boolean checkValidity = userInput.hasNextInt();
if(checkValidity) {
int userNum = userInput.nextInt();
userInput.nextLine();
System.out.println("Number " + userNum + " added to the total sum.");
sumOfNums += userNum;
counter++;
} else {
System.out.println("Invalid input. Please, enter a number.");
}
}
userInput.close();
return sumOfNums;
}
}
Hello everybody!
I just started java and I learned about control flow and now I moved on to user input, so I don't know much. The problem is this code. Works just fine if you enter valid input as I tested, nothing to get worried about. The problem is that I want to check for wrong input from user, for example when they enter a string like "asdew". I want to display the error from else statement and to move on back to asking the user for another input, but after such an input the program will enter in an infinite loop displaying "Enter the number X: Invalid input. Please, enter a number.".
Can you tell me what's wrong? Please, mind the fact that I have few notions when it comes to what java can offer, so your range of solutions it's a little bit limited.

Call userInput.nextLine(); just after while:
...
while(counter <= 10) {
System.out.print("Enter the number " + counter + ": ");
userInput.nextLine();
...

The issue is, that once you enter intput, which can not be interpreted as an int, userInput.hasNextInt() will return false (as expected). But this call will not clear the input, so for every loop iteration the condition doesn't change. So you get an infinite loop.
From Scanner#hasNextInt():
Returns true if the next token in this scanner's input can be interpreted as an int value in the default radix using the nextInt() method. The scanner does not advance past any input.
The fix is to clear the input if you came across invalid input. For example:
} else {
System.out.println("Invalid input. Please, enter a number.");
userInput.nextLine();
}
Another approach you could take, which requires less input reads from the scanner, is to always take the next line regardless and then handle the incorrect input while parsing.
public static int getSumOfInput() {
int counter = 0;
int sumOfNums = 0;
Scanner userInput = new Scanner(System.in);
while (counter <= 10) {
System.out.print("Enter the number " + counter + ": ");
String input = userInput.nextLine();
try {
int convertedInput = Integer.parseInt(input);
System.out.println("Number " + convertedInput + " added to the total sum.");
sumOfNums += convertedInput;
counter++;
} catch (NumberFormatException e) {
System.out.println("Invalid input. Please, enter a number.");
}
}
return sumOfNums;
}

Related

How can I avoid my loop to take the previous answer of the user?

I am making a program that will take a user's input on how many numbers he wants and determine the highest number between the given. After that the user will be prompt with a Yes or no question. If the user decides to say yes, the program will loop again and if not, the program will end. Now my question is why does it take the highest number from the previous run?
import java.util.Scanner;
public class IT_VILLAFLOR_Lab1_Prog2
{
public static void main(String[] Args){
int num=1,num2,Largest=0,max;
char YN;
Scanner sc = new Scanner(System.in);
System.out.print("Enter the Max Number = ");
max = sc.nextInt();
for(num=1; num<=max; num++)
{
System.out.print("Enter Number " + num + ": ");
num2 = sc.nextInt();
if(Largest<num2)
{
Largest=num2;
}
else if(num==max)
{
System.out.println("The Biggest number is " + Largest );
System.out.print( "Do you want to try again? Y/N ");
YN = sc.next().charAt(0);
if(YN =='Y'|| YN =='y')
{
num=0;
System.out.print('\f');
System.out.print("Enter the Max Number " );
max = sc.nextInt();
}
else
{
System.exit(0);
}
}
}
}
}
If the user wants to continue, you are resetting num to 0. Along with this, Largest also needs to be reset to 0.
num=0;
Largest=0; //new code
By the way, you need to change the line else if(num==max) to if(num==max) . Try the test case with max of 2 and values as 12 ,23.

Java Sum of numbers until string is entered

i've just started java programming and was wondering on how to approach or solve this problem i'm faced with.
I have to write a program that asks a user for a number and continually sums the numbers inputted and print the result.
This program stops when the user enters "END"
I just can't seem to think of a solution to this problem, any help or guidance throughout this problem would be much appreciated and would really help me understand problems like this. This is the best i could do
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while (true) {
System.out.print("Enter a number: ");
int x = scan.nextInt();
System.out.print("Enter a number: ");
int y = scan.nextInt();
int sum = x + y;
System.out.println("Sum is now: " + sum);
}
}
}
The output is supposed to look like this:
Enter a number: 5
Sum is now: 5
Enter a number: 10
Sum is now: 15
Enter a number: END
One solution would be to not use the Scanner#nextInt() method at all but instead utilize the Scanner#nextLine() method and confirm the entry of the numerical entry with the String#matches() method along with a small Regular Expression (RegEx) of "\d+". This expression checks to see if the entire string contains nothing but numerical digits. If it does then the matches() method returns true otherwise it returns false.
Scanner scan = new Scanner(System.in);
int sum = 0;
String val = "";
while (val.equals("")) {
System.out.print("Enter a number (END to quit): ");
val = scan.nextLine();
// Was the word 'end' in any letter case supplied?
if (val.equalsIgnoreCase("end")) {
// Yes, so break out of loop.
break;
}
// Was a string representation of a
// integer numerical value supplied?
else if (val.matches("\\-?\\+?\\d+")) {
// Yes, convert the string to integer and sum it.
sum += Integer.parseInt(val);
System.out.println("Sum is now: " + sum); // Display Sum
}
// No, inform User of Invalid entry
else {
System.err.println("Invalid number supplied! Try again...");
}
val = ""; // Clear val to continue looping
}
// Broken out of loop with the entry of 'End"
System.out.println("Application ENDED");
EDIT: Based on Comment:
Since since an integer can be signed (ie: -20) or unsigned (ie: 20) and the fact that an Integer can be prefixed with a + (ie: +20) which is the same as unsigned 20, the code snippet above takes this into consideration.
Do it like this:
public static void main(String[] args) throws Exception {
int sum = 0;
Scanner scan = new Scanner(System.in);
while (scan.hasNext()) {
System.out.print("Enter a number: ");
if (scan.hasNextInt())
sum += scan.nextInt();
else
break;
System.out.println("Sum is now: " + sum);
}
System.out.print("END");
}
This will end if the input is not a number (int).
As pointed out in the comments, if you want the program to stop when the user specifically enters "END", change the else-statement to:
else if (scanner.next().equals("END"))
break;

Why do I have to enter two inputs for my code to start running?

I'm using a while statement in my code, where, inside the while statement, the user inputs a number. To stop the program from looping, the user must input the word "stop". However, once I enter in a number, the output skips to another line without printing the statement I want it to print, and I have to enter my desired input again for the program to start looping.
The only time this problem DOES NOT occur is when the user inputs "stop" FIRST, then the code works fine.
This is to find the max, min, and mean of any amount of user-inputted numbers. I've tried changing the order of the else/if statements and the parameters for the said else/if statements, but nothing seems to work.
boolean stopped = false;
int numberAmount = 0;
int invalidAmount = 0;
double max = Integer.MIN_VALUE;
double min = Integer.MAX_VALUE;
double mean = 0;
while(stopped == false)
{
System.out.print("Enter a number (type "+"\""+"stop"+"\""+" to stop): ");
String originalInput = userInput.nextLine();
if(originalInput.equals("stop"))
{
stopped = true;
invalidAmount ++;
System.out.println(numberAmount+" numbers were entered with "+invalidAmount+" invalid inputs.");
}
else if(userInput.hasNextDouble())
{
double currentValue = Double.parseDouble(originalInput);
max = Math.max(max, currentValue);
min = Math.min(min, currentValue);
mean = currentValue;
numberAmount ++;
}
else if(originalInput.equals("stop") == false)
{
System.out.println("Not a number...");
invalidAmount ++;
}
}
System.out.println("The maximum is "+max+".");
System.out.println("The minimum is "+min+".");
System.out.println("The mean is "+(mean / numberAmount)+".");
userInput.close();
}
}
For example, I expect the output after inputting 7 to be
"Enter a number (type "stop" to stop):" on the next line(since the program loops to keep prompting for number input), where the user could then keep inputting numbers as they like.
Instead, the actual output is a blank line under the original prompt for user input, where the user must input their desired input AGAIN for the program to start looping.
You didn't specify in your code example what userInput is, but from the usage it looks to be an instance of Scanner. If you have a Scanner declared and then call hasNextDouble(), you will get a boolean result which fits with your usage – you have that as the condition in your if statement.
Scanner userInput = new Scanner(System.in);
boolean b = userInput.hasNextDouble();
What's missing from the picture is how hasNextDouble() works. Looking at the Javadoc for Scanner:
Returns true if the next token in this scanner's input can be interpreted as a double value using the nextDouble() method. The scanner does not advance past any input.
In order to answer true/false for whether the next input is a double or not, the scanner has to wait for input from the user before it can proceed.
All of this to say: your code looks like it's behaving normally. If you don't want to wait for user input, you need to write your code to reflect that.
I think you should invert the logic of the code, assuming you are using the Scanner, try something like this:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
boolean stopped = false;
int numberAmount = 0;
int invalidAmount = 0;
double max = Integer.MIN_VALUE;
double min = Integer.MAX_VALUE;
double mean = 0;
while (stopped == false) {
Scanner userInput = new Scanner(System.in);
System.out.print("Enter a number (type " + "\"" + "stop" + "\"" + " to stop): ");
if (userInput.hasNextDouble()) {
double currentValue = userInput.nextDouble();
max = Math.max(max, currentValue);
min = Math.min(min, currentValue);
mean = currentValue;
numberAmount++;
} else {
String originalInput = userInput.nextLine();
if (originalInput.equals("stop")) {
stopped = true;
invalidAmount++;
System.out.println(numberAmount + " numbers were entered with " + invalidAmount + " invalid inputs.");
} else {
System.out.println("Not a number...");
invalidAmount++;
}
}
}
System.out.println("The maximum is " + max + ".");
System.out.println("The minimum is " + min + ".");
System.out.println("The mean is " + (mean / numberAmount) + ".");
// userInput.close();
}
}
Basically you are checking first the input type, and only after you are collecting the value from the console. Doing it the way you have right now, you will always ask for the second input.
I don't really know the API, but I expect hasNextDouble reads another line. Check if originalInput is a double, don't read another line.

Java - String Input Exception Handling

I´m totally new to Java and I´m stuck. I have to create the game "guess the Number". I´m able to do the most parts but I´m don´t now how to handle the User Input if its a String.
I want to be able to tell the User that the Input was not correct if he enters a String, and repeatedly ask for Input. It would be great if someone could help me here :)
Here is my Code:
import java.util.Scanner;
import java.util.Random;
public class SWENGB_HW_2 {
public static void main(String[] args) {
System.out.println("Welcome to the guess the number game!\n");
System.out.println("Please specify the configuration of the game:\n");
Scanner input = new Scanner(System.in);
System.out.println("Range start number (inclusively):");
int startRange;
startRange = input.nextInt();
System.out.println("Range end (inclusively):");
int endRange;
endRange = input.nextInt();
System.out.println("Maximum number of attemps:");
int maxAttemp;
maxAttemp = input.nextInt();
System.out.println("Your Task is to guess the random number between "
+ startRange + " and " + endRange);
Random randGenerator = new Random();
int randNumber = randGenerator.nextInt((endRange - startRange) + 1)
+ startRange;
int numberOfTries = 0;
System.out
.println("You may exit the game by typing; exit - you may now start to guess:");
String exit;
exit = input.nextLine();
for (numberOfTries = 0; numberOfTries <= maxAttemp - 1; numberOfTries++) {
int guess;
guess = input.nextInt();
if (guess == randNumber) {
System.out.println("Congratz - you have made it!!");
System.out.println("Goodbye");
} else if (guess > randNumber) {
System.out.println("The number is smaller");
} else if (guess < randNumber) {
System.out.println("The number is higher");
}
}
if (numberOfTries >= maxAttemp) {
System.out.println("You reached the max Number of attempts :-/");
}
}
}
You can create a utility method that looks like this:
public static int nextValidInt(Scanner s) {
while (!s.hasNextInt())
System.out.println(s.next() + " is not a valid number. Try again:");
return s.nextInt();
}
and then, instead of
startRange = input.nextInt()
you do
startRange = nextValidInt(input);
If you want to deal with the "exit" alternative, I'd recommend something like this:
public static int getInt(Scanner s) throws EOFException {
while (true) {
if (s.hasNextInt())
return s.nextInt();
String next = s.next();
if (next.equals("exit"))
throw new EOFException();
System.out.println(next + " is not a valid number. Try again:");
}
}
and then wrap the whole program in
try {
...
...
...
} catch (EOFException e) {
// User typed "exit"
System.out.println("Bye!");
}
} // End of main.
Btw, the rest of your code looks great. I've tried it and it works like a charm :-)
You could check that the scanner has an int before you attempt to read it. You can do that by calling hasNextInt() with something like
while (input.hasNext() && !input.hasNextInt()) {
System.out.printf("Please enter an int, %s is not an int%n", input.next());
}
int startRange = input.nextInt();

How many integers, addition of integers

import java.util.Scanner;
public class InputLoop
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter an integer to continue or a non integer to finish");
while (scan.hasNextInt())
{
System.out.println("Enter an integer to continue or a non integer to finish");
int value = scan.nextInt();
System.out.print("user: ");
}
scan.next();
{
System.out.println ("You entered");
System.out.println ();
}
}
}
Where it says 'you entered' I have to have how many Integers have been input, for example '3' and then the total of the integers added together for example '56'. I don't know how to do this, how can I implement this?
Maintain a List<Integer> and add to this list every time the user enters an integer. The number of integers added will therefore simply be list.size(). With what you're doing currently, there is no way to access the user's old inputs.
You can alternatively use variables that store the total and the count (which will work fine in this case), but in my opinion using the List approach will give you much greater flexibility if you ever decide to update/revise this code, which is something you should bear in mind as a programmer.
List<Integer> inputs = new ArrayList<Integer>();
while (scan.hasNextInt()) {
...
inputs.add(scan.nextInt());
}
...
Just keep a variable named count and a variable named sum.
And change your code in the while loop to:
int value = scan.nextInt();
sum += value;
count++;
In the end you can output both after the while loop ends.
By the way you don't need to put those curly braces { } after scan.next();
They're unrelated, and will always be executed independently of scan.next();
So just change it to:
scan.next(); //I presume you want this to clear the rest of the buffer?
System.out.println("You entered " + count + " numbers");
System.out.println("The total is " + sum);
have a count variable, declared at the beginning of main and increment it.
you can also mantain a sum variable in the same way.
while (scan.hasNextInt())
{
System.out.println("Enter an integer to continue or a non integer to finish");
int value = scan.nextInt();
count++;
sum += value;
System.out.print("user: ");
}
scan.next();
{
System.out.println ("You entered");
System.out.println (count);
}
For what you want to output, you don't need to keep a history of the user's input. All you need are a running total and a count. You also don't need the last call to scan.next() or to enclose the last println calls in a separate block.
public class InputLoop
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
System.out.println("Enter an integer to continue or a non integer to finish");
int total = 0;
int count = 0;
while (scan.hasNextInt())
{
System.out.println("Enter an integer to continue or a non integer to finish");
int value = scan.nextInt();
total += value;
++count;
System.out.print("user: ");
}
System.out.println ("You entered " + count + " values with a total of " + total);
}
}

Categories

Resources