Exception Handling with External Loop - java

I'm trying to handle a user input and allow for only floats to be entered. The number of floats that can be entered is unlimited, but if two consecutive non-floats are entered the program will end. When the program ends it will print the sum of all the numbers.
The problem is that whenever I run this it immediately runs through the while loop and increases the count to 2 and breaks the loop. You're only able to enter one non-float before it cancels out.
while(true){
try{
sum+= inRead.nextFloat();
}
catch (InputMismatchException e){
if (count == 2){
System.out.println(sum);
break;
}
else{
count+=1;
}
}
}
EDIT: As a few of you had pointed out that count should be initialized before the while loop
Scanner inRead = new Scanner(System.in);
float sum = 0;
int count = 0;
while(true){
try{
sum+= inRead.nextFloat();
}
catch (InputMismatchException e){
if (count == 2){
System.out.println(sum);
break;
}
else{
count+=1;
}
}
}

Try this:
Scanner inRead = null;
float sum = 0;
int count = 0;
while(true){
try{
inRead = new Scanner(System.in);
sum+= inRead.nextFloat();
if(count == 1) {
count = 0;
}
}
catch (InputMismatchException e){
if (count == 1){
System.out.println(sum);
break;
}
else{
inRead = null;
count+=1;
}
}
}
The counter increments 2 in your code because when you encounter an InputMismatchException in a nextFloat() method. the second nextFloat() you will encounter will not work because you need to create a new Scanner for that because it causes an error earlier in your loop, and I add if(count == 1) when you need to reset it to 0 so it can satisfy your problem to stop and add all when two consecutive non-float will be inputted.

You should initialize count to 0 before while loop starts and everything goes fine. If you have initialized count to 1 then, when non float number is entered then the count becomes 2 and next time if you enter non float number then the loop terminates.

Perhaps you reused the variable count from somewhere earlier in your code causing it to break early due to an incorrect value.
You should initialize count to 0 and only increment when a non-float number is entered.
Posting more of your code could help solve the problem.

The accepted answer is broken, as constructing additional Scanner instances may actually discard parts of the input. I would strongly suggest only ever using one object to read from System.in, since it's possible (and common) for a input-reader object like Scanner to buffer data internally from the source, and replacing that object with a new instance discards any input the first object already buffered.
It's also not necessary to get the behavior you want. Instead use .next() to skip the next token if it's not valid, and use .hasNextDouble() to determine if the next token is a valid double (rather than catching the InputMismatchException).
try (Scanner in = new Scanner(System.in)) {
double sum = 0;
boolean lastInputBad = false;
while (true) {
if (in.hasNextDouble()) {
sum += in.nextDouble();
lastInputBad = false;
} else if (lastInputBad) {
break; // break the loop on a subsequent bad input
} else {
in.next(); // skip first bad input
lastInputBad = true;
}
}
System.out.println("Sum of valid inputs: " + sum);
}
Note also that I used double, rather than float. There's essentially no reason to use float in modern code; just stick to double.

Related

I have some trouble with my Java code. It won't run when telling the difference between positive and negative number when in a loop

Problem to solve
Write a program called MyWhiley1 that asks the user to type a
positive integer.
When the user types a negative value the program writes ERROR and
asks for another value.
When the user types 0 that means that the last value has been typed
and the program must write the average of the positive integers.
If the number of typed values is zero the program writes 'NO
AVERAGE'.
But I have some errors my code does not run properly if I type a positive number and then a negative number nothing happens.
public class MyWhiley1 {
public static void main(String[] arg) {
int sum = 0, list = 0;
Scanner reader = new Scanner(System.in);
System.out.println("Type a postive integer if you enter zero the list is compelete");
int number = reader.nextInt();
do {
if (number > 0) {
sum += number;
list++;
} else if (number < 0) {
System.out.println("ERROR type in a postive integer");
}
reader.close();
} while (number != 0);
if (list != 0) {
System.out.println("Average is: " + sum / list);
} else
System.out.println("NO average");
}
}
You have two issues, you are not reading the number within loop and you are closing the reader while being within loop:
int number = 0;
do
{
number = reader.nextInt();
if (number>0)
{
sum+=number;
list++;
}
else if (number<0)
{
System.out.println("ERROR type in a postive integer");
}
}while (number!=0);
reader.close();
What it looks like is happening here is that you accidentally put the reader.close() call inside the while-loop, so the Scanner is closed after the first iteration of the loop, regardless of what happens. Try putting reader.close immediately after the end of the while-loop; that should fix the issue.

Loops in Loops in Loops in Java

I need to build an array with 10 entries that the program prompts from the user, if the first entry is 9999, i need to program to quit. I also need to use try/catch for errors. Below is what I have but I can't get the variable 'number' to be recognized throughout when I input the try/catch loop... HELP!!!
public static void main(String[] args) {
int nextIndex = 1;
int[] numberFun;
numberFun = new int [10]; //creates the array with 10 entries
Scanner Keyboard = new Scanner (System.in);
int entry = 0;
//I'm trying to get the first entry to determine if it equals 9999 with this section
int firstNumber=0;
System.out.println ("Please enter a number");
firstNumber = Keyboard.nextInt();
numberFun[0] = firstNumber;
if (firstNumber != 9999)
{
while (entry < 9) //this loop is supposed to obtain the other 9 entries for the array from the user
{
int number;
System.out.println ("Please enter a number");
try // this is supposed to provide an error if the user enters something that is not a number
{
number = Keyboard.nextInt();
}
catch (Exception ex)
{
//display error message here
}
numberFun[nextIndex] = number;
++nextIndex;
++entry;
}
}
else
{
System.err.println("Command Accepted. Exiting Program.");
}
it works properly until I put the try/catch in.
Change,
int number;
to
int number = 0;
The variable that you are accessing later in the program needs to be initialized because Java will not compile if there's no guarantee that the variable you're using does not have a value to be worked with. Since you did not give number an initial value when you declared it, yet still use a try catch block to access it, Java won't know for sure whether number will have a value by the time it reaches the try catch block, which is why it's not currently working.
write firstNumber = Keyboard.nextInt(); in try catch block
and you need to initialize int number; before use

Check if input is a number in a while loop

I am starting to code in Java (never done so before), and I am having a headache with input validation.
I need that while a user inputs numbers from 0 to 1000, the while loops keeps getting executed. That works fine. The problem is I would like to check wether he inputs a number, and if he doesn't, the while loop should keep executing and waiting for the next input. So far my code only throws InputMismatchException when inputting something that is not a number and I can't see why.
Here is my code:
Scanner score = new Scanner(System.in);
int i = 0;
while (i < 1000000) {
System.out.print("Insert the new score: ");
if (score.hasNextInt()) {
i = score.nextInt();
if (i > 0) {
if (i < 200000) {
// do something
} else if (i < 500000) {
// do something
} else if (i < 700000) {
// do something
} else if (i < 100001) {
// do something
}
} else if (i < 0) {
// do something else
}
} else {
System.out.print("The score should be a number.");
i = score.nextInt();
}
}
else{
System.out.print("The score should be a number.");
i = score.nextInt(); //<---problem
}
Here you know that input was not a number so you shouldn't be trying to read it as int with nextInt(). So to consume invalid data use
next() which will return from scanner data as Sting which you can later ignore (you don't need to even store it in String variable)
or if you want to consume entire line use nextLine() (but be careful with this to avoid: Skipping nextLine() after using next(), nextInt() or other nextFoo() methods)
In your final else clause, you call score.nextInt() although you know that the next number isn't an int. That's why you get the exception. Just replace the else with this:
else {
System.out.print("The score should be a number.");
score.nextLine(); //This is the line you need to change
}
score.nextLine(); will consume the next line of input safely, and put you back in the loop.
You are receiving this error because you're telling Scanner to get an integer, even when the user does not type an integer. You need to instead accept all input (via a String) and do the validation yourself.
I've modded your code to take input as a String (Scanner#nextLine) and then attempt to update the score.
Scanner score = new Scanner(System.in);
int i = 0;
while (i < 1000000) {
System.out.print("Insert the new score: ");
if (score.hasNext()) {
final String input = score.nextLine();
try {
i = Integer.parseInt(input);
} catch (final Exception e) {
System.out.print("The score should be a number.");
continue;
}
}
if (i>0) {
if (i<200000) {
//do something
}
else if (i<500000) {
//do something
}
else if (i<700000) {
//do something
}
else if (i<100001) {
//do something
}
} else if (i<0) {
//do something else
}
}
Note the continue; statement will indefinitely ask the user for integer input until the user does, just as you requested in your question.
You may want to wrap while contents with try-catch block.
Scanner score = new Scanner(System.in);
int i = 0;
while (i < 1000000){
try{
System.out.print("Insert the new score: ");
if (score.hasNextInt()){
i = score.nextInt();
if (i>0){
if (i<200000){
do something
}
else if (i<500000){
do something
}
else if (i<700000){
do something
}
else if (i<100001){
do something
}
}else if (i<0){
do something else
}
}else{
System.out.print("The score should be a number.");
i = score.nextInt();
}
}catch(Exception e){}
}
You need to wrap your input statement inside a try/catch block and catch the InputMisMatchException. The InputMisMatchException happens because of using nextInt() in the Scanner which is expecting integer.
Scanner input = new Scanner(System.in);
int i = 0;
do {
try {
System.out.print("Enter integer ");
i = input.nextInt();
} catch (InputMismatchException e) {
//anything but integer gets caught here.
System.out.print("Please enter only integer.");
}
//necessary to take the cursor back to start of line, clear the buffer
input.nextLine();
} while (i < 1000000);
Above code example shows how to catch the InputMisMatchException.
I noticed that you have use input.hasNextInt() in your code, and all you need is to replace the following in the else block of your code.
i = score.nextInt()
with
score.nextLine();
As described in other answers, this sentence will clear the buffer waiting for next input. The exception is due to score.nextInt(), the replacement should fix it.

looping back to beginning of statement using while loop (java)

I've been given the task of making a factorial calculator that takes input from 9 to 16 using a while loop. The conditions are that if the user puts in an input that is not 9 to 16 or an int, it should loop back in the beginning and ask for input again.
My code looks like this:
Scanner myScanner;
int x = 1;
int factorial=1;
int input;
myScanner = new Scanner(System.in);
System.out.println("put in an int and i will show you its factorial");
while (true) {
input = myScanner.nextInt();
if (input<9 || input >16) {
System.out.println("please enter a valid int");
}
else{
break;
}
}
for (int i=input; i >0; i--) {
factorial *= i;
}
The problem is that this isn't really using a while loop to go back to the beginning of the code. I'm really just inputting a redundant statement to make it a while loop.
So I guess my question is, how can I make a while loop that goes back to the beginning of the loop if the wrong input is typed in?
an alternative is to use a boolean value such as
boolean validInput = false;
and loop until you have valid input. that way you won't try to calculate a value when users enter -1 in the other answer
Try doing it this way:
Scanner myScanner;
int x = 1;
int factorial=1;
int input = 0;
myScanner = new Scanner(System.in);
System.out.println("Put in an integer value between 9 and 16 and I will show you its factorial. Type -1 to exit.");
while (input != -1) {
//Try block for handling invalid string inputs
try {
input = myScanner.nextInt();
} catch (Exception e){
input = 0;
}
if (input<9 || input >16) {
System.out.println("please enter a valid int");
}
else {
for (int i=input; i >0; i--) {
factorial *= i;
//input = -1; //Optionally end here if that's how things are intended to function
}
System.out.println(factorial);
}
}
Initialize the input with a value (0). And inform the user if they type in a certain value (i.e. -1) the loop ends. Move your for loop in the else block and set the while condition as input != 1.
Alternatively, if you want the program to end if the user supplies a valid value, then in the else block, set the input value to -1 manually, or just break out of the loop using the break keyword.

How can I check for invalid input and loop until the input is valid?

I am trying to find the smallest number in the list from user input. I need to ask the user how many numbers are going to be in the list (and only accept positive numbers and no letters) and then ask them what the numbers are in the list (accepting only numbers). How can I check for this and keep looping until the numbers are valid?
public class SmallestInt {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// Initialize a Scanner to read input from the command line
Scanner input = new Scanner(System. in );
int totalIntegers = 1;
int num = 0;
int smallest = 0;
boolean inputValid = false;
/* Prompt the user and validate their input to ensure they've entered a positive (greater than zero) integer. Discard/ignore any other data.
*/
while (!inputValid)
{
System.out.print("How many integers shall we compare? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
/* Read in the candidates for smallest integer
* Validate this input as well, this time ensuring that the user has provided a valid int (any int will do at this point) and discarding any other data
*/
for (int ii = 1; ii <= totalIntegers; ii++) {
// Prompt
System.out.print("Enter value " + ii + ": ");
num = input.nextInt();
if (ii == 1) smallest = num;
else if (num < smallest) smallest = num;
}
// display smallest int
System.out.println("The smallest number entered was: " + smallest);
}
}
}
Let's come up with an sample for you so you can follow as your blueprint
first, I chose do while loop because you need to ask this question at least once.
he syntax of a do...while loop is:
do
{
//Statements
}while(Boolean_expression);
Notice that the Boolean expression appears at the end of the loop, so
the statements in the loop execute once before the Boolean is tested.
If the Boolean expression is true, the flow of control jumps back up
to do, and the statements in the loop execute again. This process
repeats until the Boolean expression is false.
Next, you need to see how you can staisfy the boolean_experssion when the input is right, so you can stop looping or if it is wrong, you keep asking the question.
The way that I really like is to use sentinel value because using break keyword really scares me.
In programming, a special value that is used to terminate a loop. The
sentinel value typically is chosen so as to not be a legitimate data
value that the loop will encounter and attempt to perform with. For
example, in a loop algorithm that computes non-negative integers, the
value "-1" can be set as the sentinel value as the computation will
never encounter that value as a legitimate processing output.
so when the input is right you change the value of i, so you can stop the looping or otherwise, showing the message and asking the question again and again till the use hits the right answer.
Code:
int i = 0;
Scanner input = new Scanner(System.in);
while (i == 0) {
System.out.println("Enter number zero plz");
int result = input.nextInt();
if(result == 0 ){
System.out.println("I entered right number");
i = 1;
} else
System.out.println("you entered the wrong number \nplz try again");
}
output:
Since this is clearly a homework / learning exercise, I won't give you code. You will learn more if you do the actual coding for yourself.
Once you have fixed the problem with the loop nesting ...
There are three problems with this code:
while (!inputValid) {
System.out.print("How many integers? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
}
First problem is that you are catching the wrong exception. Read the javadoc.
The second problem is that if nextInt fails (due to a problem parsing the integer) it puts the scanner's input cursor back to where it was before the call. And when you call it again (in the next loop iteration) it will attempt to read same "bad" number again, and again, and again, ...
You have to tell the scanner to skip over the invalid line of input so that it can read the user's next attempt.
The third problem is that you don't check that the number you just read is positive!!
Final hint: consider using while (true) and a conditional break, instead of while (condition). I think it gives a more elegant solution.
#Kick Buttowski's solution deals with the bad input skipping by creating a new Scanner on each loop iteration. Apparently it works ... but I have some doubts1 that you can rely on this always working. IMO a better solution would be to use one Scanner throughout, and use a nextLine() call to read and discard the characters up to and including the end of line.
1 - My main concern is that when you leak a Scanner that it might (in some implementations) close the underlying input stream in a finalizer. If that actually happened, then the application would stop accepting input. The current implementation does not do this, but this is not clearly specified (AFAIK).
Your while loop really isn't doing anything for you in terms of stopping the user from advancing. You are able to hit the for loop because it is inside you while loop. Change your while loop and for loop so that the for loop is outside the while loop.
while (!inputValid)
{
System.out.print("How many integers shall we compare? (Enter a positive integer): ");
try {
totalIntegers = input.nextInt();
inputValid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input!");
}
} // End while //
/* Read in the candidates for smallest integer
* Validate this input as well, this time ensuring that the user has provided a valid int (any int will do at this point) and discarding any other data
*/
for (int ii = 1; ii <= totalIntegers; ii++) {
// Prompt
System.out.print("Enter value " + ii + ": ");
num = input.nextInt();
if (ii == 1) smallest = num;
else if (num < smallest) smallest = num;
} // End for //

Categories