Exception while reading data from keyboard - java

I'm newbie in Java and I'm trying to read data from keyboard but I'm getting an exception and I don't know why and how to fix it.
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Test r = new Test();
System.out.println("Type a int number : " + r.readInteger());
System.out.println("type a double number: " + r.readDouble());
}
public int readInteger() {
Scanner input = new Scanner(System.in);
int val = 0;
while(true) {
if(input.hasNextInt()) {
val = input.nextInt();
input.nextLine();
break;
}
else {
System.out.println("Invalid data type.");
input.nextLine();
}
}
input.close();
return val;
}
double readDouble() {
Scanner input = new Scanner(System.in);
double val = 0;
while(true) {
if(input.hasNextDouble()) {
val = input.nextDouble();
input.nextLine();
break;
}
else {
System.out.println("Invalid data type.");
input.nextLine();
}
}
input.close();
return val;
}
}
The excpetion:
[roger#archroger ~]$ java Test
3
Type a int number : 3
Invalid data type.
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
at Test.readDouble(Test.java:44)
at Test.main(Test.java:8)

Don't close the scanner when it's input stream is System.in. This will close the standard input as well and statements like scanner.nextLine() will throw a NoSuchElementException when you do not check if the line is present. You check with scanner.hasNextInt() if another integer token is available and then try to get another line with scanner.getNextLine() without testing if this line exists at all. Use scanner.hasNextLine().

Related

NoSuchElementException Problem in User Input Java

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.

How to stop program from crashing?

I want the program to not crash when the user inputs anything other than a number. For example, if someone enters random letters, it should display a message saying, "input not valid, please enter a valid integer". Then prompting them if they would want to continue or not.
public static void main(String[] args) throws IOException {
BufferedWriter out = new BufferedWriter(new FileWriter("outDataFile.txt"));
Scanner input=new Scanner(System.in);
int choice = 0;
String repeat;
//Loop repeats program until user quits
do
{
//Loop repeats until a valid input is found
do
{
//Asks for number and reads value
System.out.print("\nEnter an integer and press <Enter> ");
choice = input.nextInt();
//Prints error if invalid number
if(choice <= 0)
System.out.println("Invalid Input.");
There are multiple ways to achieve that:
First is to catch the exception thrown by the Scanner and flag the loop to carry on when an exception is caught. This is not a good practise since the exception thrown by the Scanner, InputMismatchException, is an unchecked exception. Meaning the cause of this exception can be easily caught by an if/else statement.
In your case, you should try to receive the input as a String, then validate the input if it looks like a number:
Loop per character approach:
String string = scanner.nextLine();
for (int i = 0; i < string; i++) {
char ch = string.charAt(i);
if (!Character.isDigit(ch)) {
System.out.println("Input is not a number");
break; // stop the for-loop
}
}
int input = Integer.parseInt(string);
RegEx approach:
String numericRegex = "[0-9]+";
String string = scanner.nextLine();
if (!string.matches(numericRegex)) {
System.out.println("Input is not a number");
}
int input = Integer.parseInt(string);
These are popular approach to your problem, it is now up to you on how will you control your loops to repeat when an invalid input is encountered.
Use a simple try catch that will catch and a simple recursive method as such:
import java.util.InputMismatchException;
import java.util.Scanner;
public class Test
{
public static void main(String[] args)
{
System.out.println(getUserInput());
}
private static int getUserInput()
{
int choice = 0;
Scanner input = new Scanner(System.in);
System.out.println("Enter a value");
try
{
choice = input.nextInt();
} catch (InputMismatchException exception)
{
System.out.println("Invalid input. Please enter a numeric value");
getUserInput();
}
return choice;
}
}

Sanitizing user input in Java, correcting mistakes [duplicate]

I'm new to Java and I wanted to keep on asking for user input until the user enters an integer, so that there's no InputMismatchException. I've tried this code, but I still get the exception when I enter a non-integer value.
int getInt(String prompt){
System.out.print(prompt);
Scanner sc = new Scanner(System.in);
while(!sc.hasNextInt()){
System.out.println("Enter a whole number.");
sc.nextInt();
}
return sc.nextInt();
}
Thanks for your time!
Take the input using next instead of nextInt. Put a try catch to parse the input using parseInt method. If parsing is successful break the while loop, otherwise continue.
Try this:
System.out.print("input");
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("Enter a whole number.");
String input = sc.next();
int intInputValue = 0;
try {
intInputValue = Integer.parseInt(input);
System.out.println("Correct input, exit");
break;
} catch (NumberFormatException ne) {
System.out.println("Input is not a number, continue");
}
}
Shorter solution. Just take input in sc.next()
public int getInt(String prompt) {
Scanner sc = new Scanner(System.in);
System.out.print(prompt);
while (!sc.hasNextInt()) {
System.out.println("Enter a whole number");
sc.next();
}
return sc.nextInt();
}
Working on Juned's code, I was able to make it shorter.
int getInt(String prompt) {
System.out.print(prompt);
while(true){
try {
return Integer.parseInt(new Scanner(System.in).next());
} catch(NumberFormatException ne) {
System.out.print("That's not a whole number.\n"+prompt);
}
}
}
Keep gently scanning while you still have input, and check if it's indeed integer, as you need:
String s = "This is not yet number 10";
// create a new scanner
// with the specified String Object
Scanner scanner = new Scanner(s);
while (scanner.hasNext()) {
// if the next is a Int,
// print found and the Int
if (scanner.hasNextInt()) {
System.out.println("Found Int value :"
+ scanner.nextInt());
}
// if no Int is found,
// print "Not Found:" and the token
else {
System.out.println("Not found Int value :"
+ scanner.next());
}
}
scanner.close();
As an alternative, if it is just a single digit integer [0-9], then you can check its ASCII code. It should be between 48-57 to be an integer.
Building up on Juned's code, you can replace try block with an if condition:
System.out.print("input");
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("Enter a whole number.");
String input = sc.next();
int intInputValue = 0;
if(input.charAt(0) >= 48 && input.charAt(0) <= 57){
System.out.println("Correct input, exit");
break;
}
System.out.println("Input is not a number, continue");
}

About some simple exception handling in Java

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.

Inputing Integers error throwing

Can someone help me make this code neater. I would rather use parse int than a buffer reader. I want my code to loop until the user inputs a number. I couldn't figure out how to do this without the code printing out the same statement twice.
public void setAge()
{
try {
age = Integer.parseInt(scan.nextLine());
} catch (NumberFormatException e) {
System.out.println("What is your age?");
this.setAge();
}
}
Alright, my question is unclear. I am unsure of how to handle the error that a scanner throws when you don't input an integer. How do I handle this? I found "NumberFormatException" in a different post, but I am unsure of what this does. Can anyone help me with this, or is my question still unclear?
Try this:
import java.util.InputMismatchException;
import java.util.Scanner;
public class TestScanner {
public static void main(String[] args) {
Scanner scanner = null;
int age = -1;
do {
try {
scanner = new Scanner(System.in);
System.out.println("What is your age?");
age = scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("Please enter a number!");
}
} while (age == -1);
System.out.println("You are " + age + " years old.");
if (scanner != null)
scanner.close();
}
}
I get this output (the first time I enter abc instead of a number to make it retry):
What is your age?
abc
Please enter a number!
What is your age?
35
You are 35 years old.
Have fun!
Use scan.nextInt(); instead of scan.nextLine();
With this, you don't need to parse the line.
EDIT: Oops, i misread your question
Number Format Exception occurs in the java code when a programmer tries to convert a String into a number. The Number might be int,float or any java numeric values.
The conversions are done by the functions Integer.parseInt.Consider if you give the value of str is "saurabh", the function call will fail to compile because "saurabh" is not a legal string representation of an int value and NumberFormatException will occurs
You could use a scanner.
You'll need to;
import java.util.*;
static Scanner console = new Scanner(System.in);
You won't need the parse statement at all.
age = console.nextInt();
EDIT: Editing my answer after seeing your edit.
I would put the entire try in a do loop. Using a new boolean variable to control when you come out of it.
boolean excep;
do {
excep = false;
try {
age = console.nextInt();
}
catch (Exception exRef) {
System.out.println("Please input an integer");
console.nextLine();
excep = true;
}
} while (excep);
The console.nextLine() just clears a line so it doesnt re-read the last input. Sometimes it's needed.
Using this i don't receive any error notifications on the running of it.
Try this:
static boolean firstTime = true;
public static void main(String[] args) {
boolean firstTime = true;
setAge();
}
public static void setAge()
{
if(firstTime)
{
System.out.println("What is your age?");
firstTime = false;
}
Scanner scan = new Scanner(System.in);
try{
int age = scan.nextInt();
System.out.println(age);
}
catch(InputMismatchException e)
{
setAge();
}
}
if you want to print different messages you would have to do like:
import java.util.Scanner;
public class Numbers {
public static void main(String args[]) {
Numbers numbers = new Numbers();
numbers.setAge();
}
private boolean alrearyAsked = false;
private int age = 0;
static Scanner scan = new Scanner(System.in);
public void setAge()
{
try {
age = scan.nextInt();
} catch (NumberFormatException e) {
if (alrearyAsked) {
System.out.println("you typed a wrong age, please try again.");
}
else {
System.out.println("What is your age?");
}
this.setAge();
}
}
}

Categories

Resources