Write a program that calculates the average of N integers. The program should prompt the user to enter the value for N and then afterward must enter all Nnumbers. If the user enters a non-positive value for N then an exception should be thrown (and caught) with the message "N must be positive." If there is any exception as the user is entering the N numbers then an error message should be displayed and the user prompted to enter the number again. If the user does not enter an integer, the program must request the use to re-enter the value.
Am i throwing the exception correctly??
import java.util.Scanner;
import java.util.InputMismatchException;
class Playground {
public static void main(String[ ] args) {
int sum = 0, mean;
System.out.println("Please enter number of integers");
Scanner sc1 = new Scanner(System.in);
int counter = sc1.nextInt();
if ( counter <= 0 ) {
throw new InputMismatchException("N must be positive");
}
else {
System.out.println("Please enter "+counter+" numbers");
}
for (int i =0; i< counter; i++) {
int inputnum = sc1.nextInt();
if ( inputsum <= 0){
throw new InputMismatchException("Please enter again");
continue;
}
sum = sum+inputnum;
System.out.println();
}
mean = sum/counter;
System.out.println(mean);
}
}
Thrown exceptions are caught by the innermost enclosing try/catch statement which matches the exception class.
In this case the try/catch statement is outside your main method.
In other words, when an exception is thrown, it gets caught outside the main function, and your program will finish.
Exceptions are particularly useful when we have an error inside a called function and we need to report it to the caller bypassing the return value, which then doesn’t need to reserve a value for the errors.
In this line.
throw new InputMismatchException("Please enter again");
continue;
continue will never get reached by the control since throw (like a return) makes the control leave the method.
If you replace that throw with a simple System.out.println describing the problem your program will work as you expect though.
Edit: since you need a concrete example, consider your for statement. You use Scanner#nextInt() to get the next number.
It may throw an IllegalStateException if the Scanner finished its input source? Then:
try {
for (int i =0; i< counter; i++) {
/* … */
}
} catch (IllegalStateException ex) {
System.err.println(ex.getMessage());
}
If any IllegalStateException occurs, this makes the control jump in the catch clause, making it go out of the for statement with no effort.
Is this better or is there something wrong as well?
import java.util.Scanner;
import java.util.InputMismatchException;
import java.util.NoSuchElementException;
import java.util.IllegalStateException;
public class Calculator{
public static void main(String[] args){
int sum =0, mean;
System.out.println("Please enter no.");
Scanner sc1= new Scanner(System.in);
int counter = sc1.nextInt();
if ( counter <=0){
throw new InputMismatchException("not valid no.");
}
else {
try {
for (int i = 0;i<counter;i++){
int inputsum= sc1.nextInt();
sum = inputsum+sum;
System.out.println();
}
mean = sum/counter;
System.out.println(mean);
}
catch(IllegalStateException | NoSuchElementException | InputMismatchException e){
System.err.println(e.getMessage);
}
}
catch(InputMismatchException e) {
System.out.println(e.getMessage);
}
}
}
Related
I'm building a small program that checks if the user input is a number. The program runs but when my catch block catches an exception, it somehow exited the nested do-while loop it is in.
Here's my program :
package TESTCLASS;
import java.util.Scanner;
public class Apples {
static int readValidInt(Scanner in, String prompt, int min, int max){
int validUserInput;
int userInput = 0; //have to initialize this variable since I will be using it in a block, setting it to 0 for now
int checker =1;
while(!in.hasNextInt()) { //Makes sure that user inputs an Integer, not String, double, etc
System.out.println("Sorry, only numbers in integer form is allowed. Please enter your choice as an integer between 1 and 4");
in.next();
}
do {
do {
try {
userInput = in.nextInt();
checker = 0;
}
catch (Exception e) {
System.out.println("Exception detectedddd");
in.nextLine(); // This line is to *clear the buffer* for Scanner
}
}while (checker ==1 );
if ( userInput >= min && userInput <= max) {
System.out.println("you have chosen board " + userInput );
validUserInput = userInput;
}
else {
System.out.println(prompt);
validUserInput = 0;
}
}while (validUserInput==0);
return validUserInput;
}
// Main function
public static void main (String args[]) {
Scanner input = new Scanner(System.in);
System.out.println("Choose a board style");
readValidInt(input, "Bruh that's not valid", 1, 4);
}
}
Here is my output(As you can see, when I put "five", two things get printed out - "Exception detectedddd" & "Bruh that's not valid", but the latter sentence is part of the if else statement, which should not have been reached since there is an exception :
Choose a board style
100
Bruh that's not valid
five
Exception detectedddd
Bruh that's not valid
six
Exception detectedddd
Bruh that's not valid
10
Bruh that's not valid
1
you have chosen board 1
After the first input (100) you set checker = 0;. Since the value is too large you print "Bruh that's not valid" and stay within the outer loop.
That means that you read another value (five) which leads to the exception. However, since checker is already 0 (from the first pass) the inner loop is not repeated.
You need to reset checker to 1 before each start of the inner loop:
do {
checker = 1;
do {
try {
userInput = in.nextInt();
checker = 0;
}
catch (Exception e) {
System.out.println("Exception detectedddd");
in.nextLine(); // This line is to *clear the buffer* for Scanner
}
} while (checker == 1);
//... remainder of the outer loop
} while (validUserInput == 0);
I'm trying to ask the user for a number and if they enter anything wrong (not an int between 1 and 99) then catch (to prevent crash if string) and loop until enter a right number. My loop is stuck in an endless loop somehow. Note: I do have the Scanner imported and the exception imported too.
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String result;
int number;
boolean done = false;
while (true) {
try {
System.out.println("Please select a number from 1 to 99.");
number = input.nextInt();
input.nextLine();
if (number >= 1 || number <= 99) {
result = checkNumber(number);
System.out.println(result);
break;
}
} catch (InputMismatchException exception) {
}
}
}
input.nextInt() won't consume anything not an int. It will throw an exception. You ignore the exception and try to consume an int. It's still not an int. Same exception. Infinite loop. Add another input.nextLine() in your catch block.
Hello Stack overflow community,
My prompt is:
**" You will do error checking to make sure that the hour entered is in the range [0, 23]. Keep asking the user until the user enters a time within the valid range.
My program when it has the correct integer inputs (any int input really) will work correctly. However, if i enter a non-int, then everything is stuck in an infinite loop.
What am I doing wrong?
import java.util.*;
public class Tester2 {
int a; // any valid int number
public void loop()
{
Scanner sc = new Scanner(System.in);
int x=0; // terminating int
while(x==0)
{
System.out.println("Enter 0-23: ");
try
{
if(sc.hasNextInt())
{
a=sc.nextInt();
if((a>=0&&a<=23))
{
System.out.println("Success! ");
x=1;
}
else
{
System.out.println("Retry! ");
a=0;
x=0;
}
}
}
catch (NumberFormatException ex)
{
System.out.println("invalid input");
}
}
}
}
sc.hasNextInt() will return false if the next element to be read is not a valid integer. However, this element is not read at any point in your code in that case.
You should ensure that this element is read and discarded when sc.hasNextInt() is false (adding sc.next() inside an else block should do the trick).
The algorithm should take in 3 integers to an ArrayList. If the input is not an integer, then there should be a prompt. When I execute my code the catch clause is executed, but the program runs into a infinite loop. Could someone guide me into the right direction, I appreciate the help. :-D
package chapter_08;
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
public class IntegerList {
static List<Integer> numbers = new ArrayList<Integer>();
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int counter = 1;
int inputNum;
do {
System.out.print("Type " + counter + " integer: " );
try {
inputNum = input.nextInt();
numbers.add(inputNum);
counter += 1;
}
catch (Exception exc) {
System.out.println("invalid number");
}
} while (!(numbers.size() == 3));
}
}
That is because when the next int is read using nextInt() and it fails, the Scanner still contains the typed contents. Then, when re-entering the do-while loop, input.nextInt() tries to parse it again with the same contents.
You need to 'flush' the Scanner contents with nextLine():
catch (Exception exc) {
input.nextLine();
System.out.println("invalid number");
}
Notes:
You can remove the counter variable, because you're not using it. Otherwise, you could replace counter += 1 by counter++.
You can replace while (!(numbers.size() == 3)) with while (numbers.size() != 3), or even better: while (numbers.size() < 3).
When catching exceptions, you should be as specific as possible, unless you have a very good reason to do otherwise. Exception should be replaced by InputMismatchException in your case.
If inputNum = input.nextInt(); cannot be fit into an int and a InputMismatchException is raised, the input of the Scanner is not consumed.
So after the catch, it loops and it goes again here :
inputNum = input.nextInt();
with exactly the same content in the input.
So you should execute input.nextLine(); in the catch statement to discard the current input and allow a new input from the user.
Besides it makes more sense to catch InputMismatchException rather than Exception as other exception with no relation with a mismatch could occur and it would not be useful to display to the user "invalid number " if it is not the issue :
catch (InputMismatchException e){
System.out.println("invalid number ");
input.nextLine();
}
You should to use a break; in your catch(){} like so :
try {
inputNum = input.nextInt();
numbers.add(inputNum);
counter += 1;
} catch (Exception e) {
System.out.println("invalid number ");
break;
}
So if one input is not correct break your loop.
try changing
inputNum = input.nextInt();
to
String inputText=input.next();
inputNum = Integer.valueOf(inputText);
it works perfectly well.
You need to move the scanner to the next line. Add this line of code below the error message in the catch section.
input.nextLine();
I am doing a program that calculates factorials, and I wrote a loop that catches NumberFormatException and InputMismatchException. The NumberFormatException runs fine and loops back to the try block, but the InputMismatchException displays its message over and over again without looping back to the try block. I'm not sure what I'm doing wrong. Here's my code:
import java.util.*;
public class Factorial
{
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
System.out.println("Factorial Test Program\n");
boolean success = false;
while (!success)
{
try
{
System.out.print("Enter an integer number: ");
int number = s.nextInt();
if (number < 0) throw new NumberFormatException();
long f = number;
for (int i = number-1; i>0; i--)
f *= i;
if (number==0) f=1;
System.out.printf("The factorial of %s is %s.\n", number, f);
success=true;
System.out.println("Done!");
}
catch (NumberFormatException e)
{
System.out.println("Factorial of this value cannot be represented as an integer");
}
catch (InputMismatchException e)
{
System.out.println("You must enter an integer - please re-enter:");
}
}
}
}
Once an invalid integer is entered s.nextInt() continously passes the newline character through the while loop and the process repeats itself ad infinitum. On the other hand, when the NumberFormatException occurs, a valid integer has already been read, so there's no newline character being passed through to the while loop.
Adding s.nextLine() within the InputMismatchException exception block will correct this issue.
add break; in the catch block.
or make the while loop inside the try block
try {
while() {
}
} catch () {
}