Try/Catch looping in Java with user input - java

My code is supposed to take float value inputs from a user and once the user inputs 2 invalid inputs in a row (non float) the program stops and sums up the valid inputs and spits out the sum to the user. Here is the code:
System.out.println("Please input a set of float values.");
Scanner keyboard = new Scanner(System.in);
int tries = 0;
int maxTries = 2;
double sum = 0;
while (tries < 2) {
try {
while (keyboard.hasNext()){
sum += keyboard.nextDouble();
tries = 0; // reset counter because of valid input
}
}
catch (InputMismatchException e) {
System.out.println("Invalid input. Float values "
+ "only please.");
tries += 1; // tries +1 because invalid input
}
}
System.out.printf("The sum of your inputs is: %d", sum);
My exception is being thrown prematurely, once I put in one invalid input the program stops and sums up. I can't figure out how to allow the user two consecutive invalid (non float) inputs and then throw the exception. Thanks.

try{
Scanner keyboard = new Scanner(System.in);
int tries = 0;
int maxTries = 2;
double sum = 0;
while (tries < 2) {
try {
while (keyboard.hasNext()){
double d = keyboard.nextDouble();
sum += d;
tries = 0; // reset counter because of valid input
}
}
catch (InputMismatchException e) {
System.out.println("Invalid input. Float values "
+ "only please.");
tries += 1; // tries +1 because invalid input
keyboard.nextLine();
}
}
System.out.printf("The sum of your inputs is: %f", sum);
}catch(Exception e){
e.printStackTrace();
}
The exception is thrown twice because there is still input in the keyboard scanner, and it attempts to continue reading. 'flush' it by reading in a nextline.
Also, on the output, print it with a %f

Scanner gives you hasNext and hasNextXXX where XXX is type you want precisely to avoid throwing exceptions.
Anyway if user provides invalid input it will stay in stream until you consume it. You can easily do it with next() or (sometimes better) with nextLine() method. So avoid using Exceptions as main part of your flow control logic.
So change your code and instead of hasNext which allows any kind of data, use hasNextDouble().
BTW to print floating-point number you need to use %f, %d is for integers.
Scanner keyboard = new Scanner(System.in);
int tries = 0;
int maxTries = 2;
double sum = 0;
while (tries < maxTries) {
if (keyboard.hasNextDouble()) {
sum += keyboard.nextDouble();
tries = 0; // reset counter because of valid input
} else {
System.out.println("Invalid input. Float values "
+ "only please.");
keyboard.next();// consume one invalid token from user input
tries += 1; // tries +1 because invalid input
}
}
System.out.printf("The sum of your inputs is: %f", sum);
Example:
Input: 1 2 3 b 4 foo bar
Output:
1 2 a 3 a 4 aa a
Invalid input. Float values only please.
Invalid input. Float values only please.
Invalid input. Float values only please.
The sum of your inputs is: 10,000000

The easier way to handle this is to read each input line as a string (keyboard.nextLine). Then try Double.parseDouble to convert into a double, catchinh any NumberFormatException to check number of tries etc.

Related

Average calculator with user input Java - " java.util.NoSuchElementException: No line found "

I'm creating a simple average calculator using user input on Eclipse, and I am getting this error:
" java.util.NoSuchElementException: No line found " at
String input = sc.nextLine();
Also I think there will be follow up errors because I am not sure if I can have two variables string and float for user input.
import java.util.Scanner;
public class AverageCalculator {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the numbers you would like to average. Enter \"done\"");
String input = sc.nextLine();
float num = sc.nextFloat();
float sum = 0;
int counter = 0;
float average = 0;
while(input != "done"){
sum += num;
counter ++;
average = sum / counter;
}
System.out.println("The average of the "+ counter + " numbers you entered is " + average);
}
}
Thanks a lot:)
First, the precision of float is just so bad that you're doing yourself a disservice using it. You should always use double unless you have a very specific need to use float.
When comparing strings, use equals(). See "How do I compare strings in Java?" for more information.
Since it seems you want the user to keep entering numbers, you need to call nextDouble() as part of the loop. And since you seem to want the user to enter text to end input, you need to call hasNextDouble() to prevent getting an InputMismatchException. Use next() to get a single word, so you can check if it is the word "done".
Like this:
Scanner sc = new Scanner(System.in);
double sum = 0;
int counter = 0;
System.out.println("Enter the numbers you would like to average. Enter \"done\"");
for (;;) { // forever loop. You could also use 'while (true)' if you prefer
if (sc.hasNextDouble()) {
double num = sc.nextDouble();
sum += num;
counter++;
} else {
String word = sc.next();
if (word.equalsIgnoreCase("done"))
break; // exit the forever loop
sc.nextLine(); // discard rest of line
System.out.println("\"" + word + "\" is not a valid number. Enter valid number or enter \"done\" (without the quotes)");
}
}
double average = sum / counter;
System.out.println("The average of the "+ counter + " numbers you entered is " + average);
Sample Output
Enter the numbers you would like to average. Enter "done"
1
2 O done
"O" is not a valid number. Enter valid number or enter "done" (without the quotes)
0 done
The average of the 3 numbers you entered is 1.0
So there are a few issues with this code:
Since you want to have the user either enter a number or the command "done", you have to use sc.nextLine();. This is because if you use both sc.nextLine(); and sc.nextFloat();, the program will first try to receive a string and then a number.
You aren't updating the input variable in the loop, it will only ask for one input and stop.
And string comparing is weird in Java (you can't use != or ==). You need to use stra.equals(strb).
To implement the changes:
import java.util.Scanner;
public class AverageCalculator {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the numbers you would like to average. Enter \"done\"");
float sum = 0;
int counter = 0;
String input = sc.nextLine();
while (true) {
try {
//Try interpreting input as float
sum += Float.parseFloat(input);
counter++;
} catch (NumberFormatException e) {
//Turns out we were wrong!
//Check if the user entered done, if not notify them of the error!
if (input.equalsIgnoreCase("done"))
break;
else
System.out.println("'" + input + "'" + " is not a valid number!");
}
// read another line
input = sc.nextLine();
}
// Avoid a divide by zero error!
if (counter == 0) {
System.out.println("You entered no numbers!");
return;
}
// As #Andreas said in the comments, even though counter is an int, since sum is a float, Java will implicitly cast coutner to an float.
float average = sum / counter;
System.out.println("The average of the "+ counter + " numbers you entered is " + average);
}
}
import java.util.Scanner;
public class AverageCalculator {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("Enter the numbers you would like to average. Enter \"done\" at end : ");
String input = scanner.nextLine();
float num = 0;
float sum = 0;
int counter = 0;
float average = 0;
while(!"done".equals(input)){
num = Float.parseFloat(input); // parse inside loop if its float value
sum += num;
counter ++;
average = sum / counter;
input = scanner.nextLine(); // get next input at the end
}
System.out.println("The average of the "+ counter + " numbers you entered is " + average);
}
}

While loop goes infinite when moving back an iteration

Using a while loop to prompt the user to enter 3 ints to average them out, need to reprompt when the input isn't an int, so I decided to take a step back in the loop when the input isn't an int, but when I enter a non int, it's as if it consistently goes to the condition that it isn't a int, and continues to reprompt, without rechecking for a new input.
Scanner scnr = new Scanner(System.in);
String prompt = "Type an integer: ";
int num = 0;
int i = 0;
while (i < 3) {
System.out.print(prompt);
if (scnr.hasNextInt()) {
int input = scnr.nextInt();
num += input;
} else i -= 1;
i += 1;
}
double average = num / 3.0;
System.out.println("Average: " + average);
hasNextInt() only returns true if an int is already there -- it doesn't actually get input. That's what your call to nextInt() is doing. But that's never being called because hasNextInt() is always false, as you've never actually taken user input, so i is being decremented in the else block and then incremented again forever.
An alternative approach would be to use a try/catch block with nextInt() to get the next input value, and step back if that catches an exception (meaning the input was not an int).
As a previous user has mentioned the main problem is that the hasNextInt() only checks and doesn't advance your scanner forward.
Here is how I would do this code, I hope it solves the issue:
int counter = 0;
boolean flag = false;
int sum = 0;
while(!flag){
System.out.println(prompt);
if (scnr.hasNextInt()){
int input = Integer.parseInt(scnr.nextLine());
sum = sum + input;
counter++;
}else{
scnr.nextLine();
System.out.println("You didn't enter an Integer.");
}
if (counter == 3){
flag = true;
}
}
double avg = sum / 3;
System.out.println("Average: " + avg);
There are probably better ways of doing it than mine but I hope it helps, good luck!

For loop to get user input lets you enter two values for the first question, but only calculates one value

I created a small program that asks the user for 10 random numbers and it will print the sum of those numbers. I embedded it with a for loop and included a counter. Everything seems to be working fine except when I run the program, the first question allows me to enter two values, but it will still only calculate a total of 10 numbers.
Below is what I currently have and I need to understand what is going wrong when it prompts the user for the number the first time:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int sum = 0;
int counter = 0;
for (int i = 0; i < 10; i++) {
counter++;
System.out.println("Enter number #" + counter + " :");
int numberInput = scanner.nextInt();
boolean hasNextInt = scanner.hasNextInt();
if (hasNextInt) {
sum += numberInput;
} else {
System.out.println("Invalid Number");
}
}
scanner.nextLine(); // handle the next line character (enter key)
System.out.println("The sum is " + sum);
scanner.close();
}
}
In each loop, you're calling scanner.nextInt() and scanner.hasNextInt(). But you do not use the result of hasNextInt() in a meaningful way (you might have noticed that your "Invalid Number" output is not what happens if you enter something that's not a number).
The first call to nextInt() blocks until you enter a number. Then hasNextInt() will block again because the number has already been read, and you're asking whether there will be a new one. This next number is read from System.in, but you're not actually using it in this iteration (you merely asked whether it's there). Then in the next iterations, nextInt() will not block because the scanner already pulled a number from System.in and can return it immediately, so all the subsequent prompts you see actually wait for input on hasNextInt().
This amounts to 11 total input events: The firts nextInt() plus all 10 hasNextInt()s
Scanner scanner = new Scanner(System.in);
int sum = 0;
int counter = 0;
for (int i = 0; i < 10; i++) {
counter++;
System.out.println("Enter number #" + counter + " :");
int numberInput = scanner.nextInt();
// boolean hasNextInt = scanner.hasNextInt();
//if (hasNextInt) {
sum += numberInput;
// } else {
// System.out.println("Invalid Number");
//}
}
scanner.nextLine(); // handle the next line character (enter key)
System.out.println("The sum is " + sum);
scanner.close();
Don't call hasnextInt() it has no use here.
It has taken 11 inputs rather than 10.
If you remove this condition it will take 10 inputs and work fine.
Your condition have no impact on 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.

Exception Handling works only once in running program

Initially I tried to put the try statement into the while loop, however, I was encountered with several errors. The program runs perfectly except when I input a irregular character once it gives me the Printed line I inputted I created, however, when I inputted another one again, the line does not pop up and rather gives me a format exception error.
AddNumbersrealone2.java
import java.io.*;
// create the class
public class AddNumbersrealone2
{
// allows i/o
public static void main (String [] args) throws IOException
{ // initalize variables and strings
BufferedReader myInput = new BufferedReader (new InputStreamReader (System.in));
String sumNumbers;
//String go;
double num ;
double total = 0.0;
// asks user questions and instructions
System.out.println("Hello, the following program will ask for your input of a number ");
System.out.println("Each time you input a number a running total will be added to each previous number") ;
System.out.println("Once ready input a number to start!");
// try and catch block
try {
num = 0;
// while statement if this occurs stop the program, in this case if a negative integer is inputted
while (num >= 0) {
// Contious question asked
System.out.println("Input another number...");
sumNumbers = myInput.readLine();
num = Double.parseDouble (sumNumbers);
// calculates number (Running total)
total = total + num;
System.out.println(total);
// end error trap
}
}
catch (Exception e){
System.out.println("Please refrain from entering regular characters!");
num = 0;
// re- while statement if this occurs stop the program, in this case if a negative integer is inputted
while ( num >= 0) {
// input question after a character is inputted
System.out.println("Please input a number: ");
sumNumbers = myInput.readLine();
num = Double.parseDouble (sumNumbers);
total = total + num;
System.out.println(total);
// ending statement
}
}
System.out.println("You entered a negative number, the program will exit now");
System.out.println("Good-bye!");
// Complete class body
}
}
You want something to catch the exception around the Double.parseDouble
for example.
while(num >= 0)
{
// input question after a character is inputted
System.out.println("Please input a number: ");
sumNumbers = myInput.readLine();
try{
num = Double.parseDouble (sumNumbers);
total = total + num;
System.out.println(total);
} catch(Exception e)
{
System.out.println("Please enter a proper number");
}
// ending statement
}
Your problem is that as soon as the first exception is thrown, your program becomes caught up inside the while() loop inside of your catch statement. Thus, if another invalid input is entered, it is dealt with in that second while loop where you have no try-catch statement. A good fix would be to have your try statement encompass only the line where you say num = Double.parseDouble (sumNumbers);. When you catch the exception, end it with a continue; statement so that your program loops back the beginning and asks for another input.

Categories