Loop will not end despite the terminating expression - java

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).

Related

Repeatedly check whether integer input has leading zeroes

I need the user to enter an integer input, check whether it starts by 0 and tell the user to enter another integer if that is the case
I tried parsing the integer input to a string, that works but only once. The string cannot be edited when program loops
I think the solution should not at all involve strings because i need the program to loop and check over and over until the input is valid (ie has no leading zeroes)
Splitting each digit of the int into an array does not work also because the ways i found pass by string.
public static void main(String[] args){
Scanner key = new Scanner(System.in);
int in= 0;
boolean looper=true;
while (looper == true) {
System.out.println("Enter an integer");
in = key.nextInt();
/* check whether in has any leading zeroes, example of
wrong input: 09999, 0099*/
if (/*in has no leading zeroes*/)
looper = false;
}
key.close();
}
Maybe another answer would be to have a method that creates a brand new string every time the program loops, so maybe like a recursion that automatically creates strings, not sure if that's even a thing though.
You can make it cleaner by using a do-while loop instead of while(true). Note that an integer starting with 0 is an octal number e.g.
public class Main {
public static void main(String[] args) {
int x = 06;
System.out.println(x);
// x = 09; // Compilation error - out of range
}
}
Thus, 06 is a valid integer. For your requirement, you can input to a String variable and prompt the user to again if it starts with a zero. If the input does not start with a zero, try parsing it to an int and process it if it succeeds; otherwise, loopback e.g.
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner key = new Scanner(System.in);
String input = "";
int in = 0;
boolean valid = true;
do {
System.out.print("Enter an integer: ");
input = key.nextLine();
if (input.startsWith("0")) {
System.out.println("Invalid input");
valid = false;
} else {
try {
in = Integer.parseInt(input);
System.out.println("You entered " + in);
// ... process it
valid = true;
} catch (NumberFormatException e) {
System.out.println("Invalid input");
valid = false;
}
}
} while (!valid);
}
}
A sample run:
Enter an integer: 09999
Invalid input
Enter an integer: xyz
Invalid input
Enter an integer: 123
You entered 123
As an aside, never close a Scanner(System.in) because it also closes System.in and there is no way to open it without rebooting the JVM.

I put my try catch in a do while loop, but the commands after the do-while loop continue running even though there is an exception caught

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);

Asking for an integer [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I try to solve the next task:
1. Asking the user for a positive integer.
2. If the user adds a negative or a real number or both, the next error message should be displayed on the console: "wrong input".
That is what I have done so far.
Scanner sc = new Scanner(System.in);
System.out.print("Please, add a positive integer! ");
int num = sc.nextInt();
if (num < 0) {
System.out.println("wrong input");
}
Everything works well, except I cannot make sure that the user receives the error message if he/she doesn't type an integer but a real number. In this case, the program goes wrong.
I would appreciate the help.
import java.util.Scanner;
import java.util.InputMismatchException;
public class ScanTest
{
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
boolean badInput = true;
int num;
// Keep asking for input in a loop until valid input is received
while(badInput)
{
System.out.print("Please, add a positive integer! ");
try {
num = Integer.parseInt(sc.nextLine());
// the try catch means that nothing below this line will run if the exception is encountered
// control flow will move immediately to the catch block
if (num < 0) {
System.out.println("Please input a positive value.");
} else {
// The input is good, so we can set a flag that allows us to exit the loop
badInput = false;
}
}
catch(InputMismatchException e) {
System.out.println("Please input an integer.");
}
catch(NumberFormatException e) {
System.out.println("Please input an integer.");
}
}
}
}
Occasionally I find it easier to read in a string and then try and parse it. This presumes you would like to repeat the prompt until you get a valid number.
Scanner sc = new Scanner(System.in);
int num = -1;
while (num < 0) {
System.out.print("Please, add a positive integer! ");
String str = sc.nextLine();
try {
num = Integer.parseInt(str);
} catch (NumberFormatException e) {
System.out.println("Only integers are accepted.");
continue;
}
if (num < 0) {
System.out.println("Input is < 0.");
}
}
Read about NumberFormatException here.
When you're using Scanner.nextInt() the input is expected to be an integer. Inputting anything else, including a real number, will throw an InputMismatchException. To make sure invalid input doesn't stop your program, use a try/catch to handle the exception:
int num;
try {
num = sc.nextInt();
// Continue doing things with num
} catch (InputMismatchException e) {
// Tell the user the error occured
}

Java program calculating mean with exceptions

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);
}
}
}

WHILE Loop Condition Does Not Validate Input

I have a WHILEloop which checks for marks for a particular student. However, it does not loop if the value is invalid (input less than 0 and more than 100):
int marks= -1;
System.out.print("Student Marks (/100): ");
while (((marks< 0) || (marks> 100))) {
try {
marks = Integer.parseInt(sc.nextLine());
break;
} catch (NumberFormatException nfe) {
System.err.println("Error: Invalid Mark(s)");
System.out.print("Student Marks (/100): ");
}
}
It does catches exception if characters other than numbers are entered.
But it does not loop again if value if less than 0 or more than 100.
I have tried making many changes to it but to no result.
Any help given is appreciated!
You should remove the break statement, since it breaks you out of the loop regardless of what value of marks was input.
Always use continue instead of break if you want to keep the loop running.
You may check the marks inside the while loop with an if condition and here you may use break -
import java.util.Scanner;
public class TakeInput{
public static void main(String args[]){
int marks= -1;
Scanner sc = new Scanner(System.in);
System.out.print("Student Marks (/100): ");
while (sc.hasNext()) {
try {
marks = Integer.parseInt(sc.nextLine());
if(marks<0 || marks>100){
break;
}
//do something
// with the marks
//take new marks
System.out.print("Student Marks (/100): ");
} catch (NumberFormatException nfe) {
System.err.println("Error: Invalid Mark(s)");
System.out.print("Student Marks (/100): ");
}
}
}
}
Now as long as you enter anything except a number n when n<0 || n>100 will continue the loop. Any NumberFormatExeption take you to the catch block.
If you enter 34 then it goes to the while block and prompt for a next number.
Then if you enter 56 then it dose the same thing.
When you enter any String rather than a number than it goes to the catch block
This process continues until you enter a invalid number (n>100 || n<100). Pressing Ctrl+C also exit you from the loop.
Hope it will help you.
Thanks a lot.

Categories