I have a problem when trying to execute try-catch statement inside do while loop.I ask user to first enter letter and then a number and if he enters number correctly the program ends.If he enters letter instead of number the program should say "An error occurred please enter number " and ask user to enter number again but every time i type letter instead of number the program goes into an infinite loop and won't allow me to enter new value.
And just goes
"An error occurred you must enter number"
"Please enter number".
public class OmaBrisem {
public static void main(String[] args) {
Scanner tastatura = new Scanner(System.in);
boolean b = true;
int a = 0;
String r = "";
System.out.println("Please enter a letter");
r = tastatura.next();
do {
try {
System.out.println("Please enter numerical value");
a = tastatura.nextInt();
b = true;
} catch (Exception e) {
System.out.println("An error occured you must enter number");
b = false;
}
} while (!b);
}
}
Here's your problem. If the user enters a non-number where you expect a number, your nextInt() will raise an exception but it will not remove the letter from the input stream!
That means when you loop back to get the number again, the letter will still be there and your nextInt() will once again raise an exception. And so on, ad infinitum (or at least until the heat death of the universe, or the machine finally breaks down, whichever comes first).
One way to fix this would be to actually read/skip the next character when nextInt() fails so that it's removed from the input stream. You could basically do this with Scanner.findInLine(".") until Scanner.hasNextInt() returns true.
The following code shows one way to do this:
import java.util.Scanner;
public class MyTestProg {
public static void main(String [] args) {
Scanner inputScanner = new Scanner(System.in);
System.out.print("Enter letter, number: ");
// Get character, handling newlines as needed
String str = inputScanner.findInLine(".");
while (str == null) {
str = inputScanner.nextLine();
str = inputScanner.findInLine(".");
}
// Skip characters (incl. newline) until int available.
while (! inputScanner.hasNextInt()) {
String junk = inputScanner.findInLine(".");
if (junk == null) {
junk = inputScanner.nextLine();
}
System.out.println("Ignoring '" + junk + "'");
}
// Get integer and print both.
int num = inputScanner.nextInt();
System.out.println("Got '" + str + "' and " + num);
}
}
And the following transcript shows it in action:
Enter letter, number: Abcde42
Ignoring 'b'
Ignoring 'c'
Ignoring 'd'
Ignoring 'e'
Got 'A' and 42
I realized that my program ignores the Scanner object tastatura in try block whenever i insert wrong value and do while loop starts again so i created new object of Scanner class and called it tastatura2 and my program works fine.
Scanner tastatura = new Scanner(System.in);
boolean b = true;
int a = 0;
String r = "";
System.out.println("Please enter a letter");
r = tastatura.next();
do {
try {
Scanner tastatura2 = new Scanner(System.in);
System.out.println("Please enter numerical value");
a = tastatura2.nextInt();
b = true;
} catch (Exception e) {
System.out.println("An error occured you must enter number");
b = false;
}
} while (!b);
Just add tastatura.nextLine() in the catch block to discard the last input.
You can get out of the loop by break; when the Exception is caught ... So just add :
break;
on your catch Block :)
The catch clause would look like this :
catch (Exception e) {
System.out.println("An error occured you must enter number");
b = false;
break;
}
Related
I'm confused while using an Java program I created.
public static void main(String[] args) {
Scanner scanner1 = new Scanner(System.in);
int input1 = 0;
boolean Input1Real = false;
System.out.print("Your first input integer? ");
while (!Input1Real) {
String line = scanner1.nextLine();
try {
input1 = Integer.parseInt(line);
Input1Real = true;
}
catch (NumberFormatException e) {
System.out.println("Use an integer! Try again!");
System.out.print("Your first input integer? ");
}
}
System.out.println("Your first input is " + input1);
}
Initially, when a user Ctrl+D during the input, it will promptly end the program and display an error in the form of this,
Your first input integer? ^D
Class transformation time: 0.0073103s for 244 classes or 2.9960245901639343E-5s per class
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.base/java.util.Scanner.nextLine(Scanner.java:1651);
at Playground.Test1.main(Test1.java:13)
Doing a bit of research I note that Ctrl+D terminates the input of sort. Therefore, I tried add few more lines to my codes to prevent the error from appearing again and instead printing a simple "Console has been terminated successfully!" and as far as my skills can go.
public static void main(String[] args) {
Scanner scanner1 = new Scanner(System.in);
int input1 = 0;
boolean Input1Real = false;
System.out.print("Your first input integer? ");
while (!Input1Real) {
String line = scanner1.nextLine();
try {
try {
input1 = Integer.parseInt(line);
Input1Real = true;
}
catch (NumberFormatException e) {
System.out.println("Use an integer! Try again!");
System.out.print("Your first input integer? ");
}
}
catch (NoSuchElementException e) {
System.out.println("Console has been terminated successfully!");
}
}
System.out.println("Your first input is " + input1);
}
In the end, I still got the same error.
Got it!, the code hasNext() will ensure that the error will not appear. This method is to check whether there is another line in the input of the scanner and to check if its filled or empty. I am also using null to check my statement after passing the loop so the program stops if the input value is still null while keeping the function of Ctrl+D.
public static void main(String[] args) {
Integer input1 = null;
System.out.println("Your first input integer? ");
Scanner scanner1 = new Scanner(System.in);
while(scanner1.hasNextLine()) {
String line = scanner1.nextLine();
try {
input1 = Integer.parseInt(line);
break;
}
catch (NumberFormatException e) {
System.out.println("Use an integer! Try again!");
System.out.println("Your first input integer? ");
}
}
if (input1 == null) {
System.out.println("Console has been terminated successfully!");
System.exit(0);
}
System.out.println(input1);
}
This solution is not prefect of course but I would appreciate if there were much simpler options.
Professor requires us to write a program that will give the user prompt to enter two float (or double) values. If the values inputted are correct then display the inputted two values. If user enters characters instead of numbers or if they enter invalid numbers then the program will display the error message and ask the user to re-enter the correct values again. It only exits when the correct input is received and displayed.
However, I wrote a program that will only work if the user input the two right doubles. Can someone helps me to change the line about catching errors? Thanks.
import java.util.Scanner;
public class FiveSecond {
static void printMenu() {
System.out.println("Welcome to get two doubles program:");
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
boolean valid = false;
double first = 0;
double second = 0;
printMenu();
while(!valid) {
System.out.print("Enter two doubles, seperate by space ");
try {
first = Double.parseDouble(scan.next());
second = Double.parseDouble(scan.next());
} catch (NumberFormatException e) {
System.out.println("Try again");
}
valid = true;
}
System.out.println("You entered valid choice: " + first + " " +second);
System.out.println("Thank you for giving your choice.");
scan.close();
}
}
Try this:
catch (NumberFormatException e) {
System.out.println("Try again");
continue;
}
In addition to the previous comments, you have to be careful, because the scanner will 'remember' a previously correct double if you don't reset it :
EDITED: Thanks to #Stultuske comment
while (!valid) {
System.out.print("Enter two doubles, seperate by space ");
try {
first = Double.parseDouble(scan.next());
second = Double.parseDouble(scan.next());
valid = true;
}
catch (NumberFormatException e) {
System.out.println("Try again");
scan.nextLine(); // <------- Important line
}
}
I am a noob in programming.
I wanted to write code for a prog which asks user to enter value until an integer is entered.
public class JavaApplication34 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int flag = 0;
while(flag == 0) {
int x = 0;
System.out.println("Enter an integer");
try {
x = sc.nextInt();
flag = 1;
} catch(Exception e) {
System.out.println("error");
}
System.out.println("Value "+ x);
}
}
}
I think the code is correct and it should ask me to enter the value again if i have entered anything other than an integer.
But when i run it , and say i enter xyz
it iterates infinite time without asking me to enter the value.
test run :
Enter an integer
xyz
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
Enter an integer
error
Value 0
When a scanner throws an InputMismatchException, the scanner will not
pass the token that caused the exception.
Hence sc.nextInt() reads the same token again and throws the same exception again.
...
...
...
catch(Exception e){
System.out.println("error");
sc.next(); // <---- insert this to consume the invalid token
}
You can change your logic as shown below :
int flag = 0;
int x = 0;
String str="";
while (flag == 0) {
System.out.println("Enter an integer");
try {
str = sc.next();
x = Integer.parseInt(str);
flag = 1;
} catch (Exception e) {
System.out.println("Value " + str);
}
}
Here we have first read the input from Scanner and then we are trying to parse it as int, if the input is not an integer value then it will throw exception. In case of exception we are printing what user has enter. When user enters an integer then it will parsed successfully and value of flag will update to 1 and it will cause loop to exit.
In the error case, you need to clear out the string you've entered (for instance, via nextLine). Since it couldn't be returned by nextInt, it's still pending in the scanner. You also want to move your line outputting the value into the try, since you don't want to do it when you have an error.
Something along these lines:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int flag = 0;
while(flag == 0)
{
int x = 0;
System.out.println("Enter an integer");
try
{
x = sc.nextInt();
flag = 1;
System.out.println("Value "+ x);
}
catch (Exception e){
System.out.println("error");
if (sc.hasNextLine()) { // Probably unnecessary
sc.nextLine();
}
}
}
}
Side note: Java has boolean, there's no need to use int for flags. So:
boolean flag = false;
and
while (!flag) {
and
flag = true; // When you get a value
The answers to this question might help you
It makes use of Scanners .hasNextInt() function!
There are several questions I would like to ask, please refer the comment part I have added in the code, Thanks.
package test;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
/* Task:
prompt user to read two integers and display the sum. prompt user to read the number again if the input is incorrect */
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean accept_a = false;
boolean accept_b = false;
int a;
int b;
while (accept_a == false) {
try {
System.out.print("Input A: ");
a = input.nextInt(); /* 1. Let's enter "abc" to trigger the exception handling part first*/
accept_a = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.nextLine(); /* 2. I am still not familiar with nextLine() parameter after reading the java manual, would you mind to explain more? All I want to do is "Clear Scanner Buffer" so it wont loop for the println and ask user to input A again, is it a correct way to do it? */
}
}
while (accept_b == false) {
try {
System.out.print("Input B: ");
b = input.nextInt();
accept_b = true;
} catch (InputMismatchException ex) { /*3. Since this is similar to the above situation, is it possible to reuse the try-catch block to handling b (or even more input like c d e...) exception? */
System.out.println("Input is Wrong");
input.nextLine();
}
}
System.out.println("The sum is " + (a + b)); /* 4. Why a & b is not found?*/
}
}
I am still not familiar with nextLine() parameter after reading the java manual, would you mind to explain more? All I want to do is "Clear Scanner Buffer" so it wont loop for the println and ask user to input A again, is it a correct way to do it?
The use of input.nextLine(); after input.nextInt(); is to clear the remaining content from the input stream, as (at least) the new line character is still in the buffer, leaving the contents in the buffer will cause input.nextInt(); to continue throwing an Exception if it's no cleared first
Since this is similar to the above situation, is it possible to reuse the try-catch block to handling b (or even more input like c d e...) exception?
You could, but what happens if input b is wrong? Do you ask the user to re-enter input a? What happens if you have 100 inputs and they get the last one wrong?You'd actually be better off writing a method which did this for, that is, one which prompted the user for a value and returned that value
For example...
public int promptForIntValue(String prompt) {
int value = -1;
boolean accepted = false;
do {
try {
System.out.print(prompt);
value = input.nextInt();
accepted = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.nextLine();
}
} while (!accepted);
return value;
}
Why a & b is not found?
Because they've not been initialised and the compiler can not be sure that they have a valid value...
Try changing it something more like.
int a = 0;
int b = 0;
Yes, it's okay. And will consume the non-integer input.
Yes. If we extract it to a method.
Because the compiler believes they might not be initialized.
Let's simplify and extract a method,
private static int readInt(String name, Scanner input) {
while (true) {
try {
System.out.printf("Input %s: ", name);
return input.nextInt();
} catch (InputMismatchException ex) {
System.out.printf("Input %s is Wrong%n", input.nextLine());
}
}
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int a = readInt("A", input);
int b = readInt("B", input);
System.out.println("The sum is " + (a + b));
}
I have put comment to that question line.
package test;
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean accept_a = false;
boolean accept_b = false;
int a=0;
int b=0;
System.out.print("Input A: ");
while (accept_a == false) {
try {
a = input.nextInt(); // it looks for integer token otherwise exception
accept_a = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.next(); // Move to next other wise exception // you can use hasNextInt()
}
}
System.out.print("Input B: ");
while (accept_b == false) {
try {
b = input.nextInt();
accept_b = true;
} catch (InputMismatchException ex) {
System.out.println("Input is Wrong");
input.next();
}
}
System.out.println("The sum is " + (a + b)); // complier doesn't know wheather they have initialised or not because of try-catch blocks. so explicitly initialised them.
}
}
Check out this "nextLine() after nextInt()"
and initialize the variable a and b to zero
nextInt() method does not read the last newline character.
Why is good practice to empty the 'Garbage' from the input buffer in a block of code like this? What would happen if I didn't?
try{
age = scanner.nextInt();
// If the exception is thrown, the following line will be skipped over.
// The flow of execution goes directly to the catch statement (Hence, Exception is caught)
finish = true;
} catch(InputMismatchException e) {
System.out.println("Invalid input. age must be a number.");
// The following line empties the "garbage" left in the input buffer
scanner.next();
}
Assuming you are reading from the scanner in a loop, if you don't skip the invalid token, you will keep reading it forever. That's what scanner.next() does: it moves the scanner to the next token. See the below simple example, which outputs:
Found int: 123
Invalid input. age must be a number.
Skipping: abc
Found int: 456
Without the String s = scanner.next() line, it would keep printing "Invalid input" (you can try by commenting out the last 2 lines).
public static void main(String[] args) {
Scanner scanner = new Scanner("123 abc 456");
while (scanner.hasNext()) {
try {
int age = scanner.nextInt();
System.out.println("Found int: " + age);
} catch (InputMismatchException e) {
System.out.println("Invalid input. age must be a number.");
String s = scanner.next();
System.out.println("Skipping: " + s);
}
}
}