I am learning Java and am learning I/O w/ java.util.Scanner. Specifically I am learning Scanner methods.
import java.util.Scanner;
public class ScannerTest {
public static void main(String args[]) {
Scanner s = new Scanner(System.in);
int result;
while (s.hasNextInt()) {
result += s.nextInt();
}
System.out.println("The total is " + result);
}
}
Because you're checking only
while (s.hasNextInt())
You could use try catch to catch the exception (see documentation here) you get when the program quits, so you can show your error message in the catch block without making the program close.
Perhaps you should try parsing each line:
public static void main(String args[]){
int sum = 0;
final Scanner scanner = new Scanner(System.in);
System.out.println("Enter a series of integers. Press 'q' to quit.");
while(true){
final String line = scanner.nextLine();
if(line.equals("q"))
break;
try{
final int number = Integer.parseInt(line);
sum += number;
}catch(Exception ex){
System.err.printf("Invalid: %s | Try again\n", ex.getMessage());
}
}
System.out.printf("The sum is %,d" , sum);
}
The idea is to read input line by line and attempt parsing their input as an integer. If an exception is thrown (meaning they entered an invalid integer) it would throw an exception in which you could handle in what ever way you want to. In the sample above, you are simply printing the error message and prompting the user to type in another number.
You can do this for the while loop (not tested though):
while (s.hasNextLine()) {
String line = s.nextLine();
int parsedInteger;
try {
parsedInteger = Integer.parseInt(line);
} catch(NumberFormatException numEx) {
if(line.startsWith("q")) break;
else {
System.out.println("please enter valid integer or the character 'q'.");
continue;
}
}
result += parsedInteger;
}
s.close();
Instead of scanning for int's you can scan for lines and then then parse each line as an int. I feel the advantage of this approach is that if any of your int's are malformed you can then handle them appropriately by say displaying an error message to the user.
OR, based on the answer by pinckerman, you can also do this.
while (s.hasNextInt()) {
try {
result += s.nextInt();
} catch(InputMismatchException numEx) {
break;
}
}
s.close();
A smart way you can do it and I've tried before is you use Integer.parseInt(String toParse); This returns an int and will reject all non numerical chars.
while (scanner.hasNextInt()) {
int i = Integer.parseInt(scanner.nextInt());
result += i;
if (result < 2147483648 && result > -2147483648) {
try{
throw new IndexOutOfBoundsException();
catch (Exception e) {e.printStackTrace();}
}
Try the following way:
int result = input.nextInt;
this will define your variable for result.
The only problem in your code is "not initializing" result. Once you initialized code will work properly. However, please do not forget you need to tell compiler EOF. Compiler can only understand the stop of the input on the console by EOF. CTRL Z is EOF for windows Eclipse IDE.
Related
This question already has answers here:
How to handle infinite loop caused by invalid input (InputMismatchException) using Scanner
(5 answers)
Closed last month.
So I'm building a program which takes ints from user input. I have what seems to be a very straightforward try/catch block which, if the user doesn't enter an int, should repeat the block until they do. Here's the relevant part of the code:
import java.util.InputMismatchException;
import java.util.Scanner;
public class Except {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean bError = true;
int n1 = 0, n2 = 0, nQuotient = 0;
do {
try {
System.out.println("Enter first num: ");
n1 = input.nextInt();
System.out.println("Enter second num: ");
n2 = input.nextInt();
nQuotient = n1/n2;
bError = false;
}
catch (Exception e) {
System.out.println("Error!");
}
} while (bError);
System.out.printf("%d/%d = %d",n1,n2, nQuotient);
}
}
If I enter a 0 for the second integer, then the try/catch does exactly what it's supposed to and makes me put it in again. But, if I have an InputMismatchException like by entering 5.5 for one of the numbers, it just shows my error message in an infinite loop. Why is this happening, and what can I do about it? (By the way, I have tried explicitly typing InputMismatchException as the argument to catch, but it didn't fix the problem.
You need to call next(); when you get the error. Also it is advisable to use hasNextInt()
catch (Exception e) {
System.out.println("Error!");
input.next();// Move to next other wise exception
}
Before reading integer value you need to make sure scanner has one. And you will not need exception handling like that.
Scanner scanner = new Scanner(System.in);
int n1 = 0, n2 = 0;
boolean bError = true;
while (bError) {
if (scanner.hasNextInt())
n1 = scanner.nextInt();
else {
scanner.next();
continue;
}
if (scanner.hasNextInt())
n2 = scanner.nextInt();
else {
scanner.next();
continue;
}
bError = false;
}
System.out.println(n1);
System.out.println(n2);
Javadoc of Scanner
When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.
YOu can also try the following
do {
try {
System.out.println("Enter first num: ");
n1 = Integer.parseInt(input.next());
System.out.println("Enter second num: ");
n2 = Integer.parseInt(input.next());
nQuotient = n1/n2;
bError = false;
}
catch (Exception e) {
System.out.println("Error!");
input.reset();
}
} while (bError);
another option is to define Scanner input = new Scanner(System.in); inside the try block, this will create a new object each time you need to re-enter the values.
To follow debobroto das's answer you can also put after
input.reset();
input.next();
I had the same problem and when I tried this. It completely fixed it.
As the bError = false statement is never reached in the try block, and the statement is struck to the input taken, it keeps printing the error in infinite loop.
Try using it this way by using hasNextInt()
catch (Exception e) {
System.out.println("Error!");
input.hasNextInt();
}
Or try using nextLine() coupled with Integer.parseInt() for taking input....
Scanner scan = new Scanner(System.in);
int num1 = Integer.parseInt(scan.nextLine());
int num2 = Integer.parseInt(scan.nextLine());
To complement the AmitD answer:
Just copy/pasted your program and had this output:
Error!
Enter first num:
.... infinite times ....
As you can see, the instruction:
n1 = input.nextInt();
Is continuously throwing the Exception when your double number is entered, and that's because your stream is not cleared. To fix it, follow the AmitD answer.
#Limp, your answer is right, just use .nextLine() while reading the input. Sample code:
do {
try {
System.out.println("Enter first num: ");
n1 = Integer.parseInt(input.nextLine());
System.out.println("Enter second num: ");
n2 = Integer.parseInt(input.nextLine());
nQuotient = n1 / n2;
bError = false;
} catch (Exception e) {
System.out.println("Error!");
}
} while (bError);
System.out.printf("%d/%d = %d", n1, n2, nQuotient);
Read the description of why this problem was caused in the link below. Look for the answer I posted for the detail in this thread.
Java Homework user input issue
Ok, I will briefly describe it. When you read input using nextInt(), you just read the number part but the ENDLINE character was still on the stream. That was the main cause. Now look at the code above, all I did is read the whole line and parse it , it still throws the exception and work the way you were expecting it to work. Rest of your code works fine.
So I am trying to write a method that checks if scanner input is an int, and loops errormessage until the user inputs an int. The method below works aslong as the usser doesn't give more than 1 wrong input. If I type muliple letters and then an int, the program will crash. I think it might have something to do with my try catch only catching 1 exception but not sure, and cant seem to get it to work. Does anyone know how I can fix this?
calling on method:
System.out.println("Write the street number of the sender: ");
int senderStreetNumber = checkInt(sc.nextLine);
method:
public static int checkInt (String value){
Scanner sc = new Scanner(System.in);
try{
Integer.parseInt(value);
} catch(NumberFormatException nfe) {
System.out.println("ERROR! Please enter a number.");
value = sc.nextLine();
checkInt(value);
}
int convertedValue = Integer.parseInt(value);
return convertedValue;
}
Something like this. Did not code it in an IDE, just from brain to keyboard.
Hope it helps. Patrick
Scanner sc = new Scanner(System.in);
int senderStreetNumber;
boolean ok = false;
while(!ok) {
System.out.println("Write the street number of the sender: ");
try {
senderStreetNumber = Integer.parseInt(sc.nextLine());
ok = true;
} catch (NumberFormatException nfe) {
System.out.println("ERROR! Please enter a number.");
}
}
Your logic of recursive is not good.
Let me try to explain your error...
The first time you get in the function you "check if the value is a int)
if not you to recurcive.
Lets say the second time is good.
then you cto the converted value
then the recurvice kicks in and you come back to the first time you get in the fucntion.
Then it does again the converted value and you don't catch that Exception so your application crash
This works.., just modified your program..tested
public static int checkInt(String value) {
Scanner sc = new Scanner(System.in);
try {
return Integer.parseInt(value);
}catch (Exception e) {
System.out.println("Error please enter correct..");
value = sc.nextLine();
return checkInt(value);
}
//int convertedValue = Integer.parseInt(value);
//return convertedValue;
}
I've copied part of the instructions below, and I can code pretty much every part on its own, but getting the control flow together is giving me massive doubts about my ability.
One of my biggest problems is the int gameChanger. Im supposed to immediately verify if it is a integer or not, and loop back if its not. But then Im also supposed to check to see if thebuser ever types "exit". But the input variable for my scanner instance is an integer... So Im stumped. I can use a try catch to check the missmatchexception once the input is being read in, but that doesnt solve the exit issue nor am I able to come up with solid logic to get the try catch to loop back if it indeed isnt an integer. Im thinking a do while loop but I havent gotten it to work.
Instructions:
You can whether the input is a number before attempting to consume it.
int num;
while (true) {
if (scanner.hasNextInt()) {
num = scanner.nextInt();
break;
} else {
// read whatever is there instead.
String line = scanner.nextLine();
if (line.equals("exit"))
System.exit(0);
System.out.println("Please enter a number");
}
}
System.out.println("Number entered " + num);
This gets the job done. Try it out.
import java.util.Scanner;
public class MyCode
{
public static void main(String[] args)
{
String gameInput = ".";
int gameNumber = 0;
boolean inputLoop = true;
Scanner input = new Scanner(System.in);
while(inputLoop == true)
{
try
{
System.out.print("Please enter a valid game number: ");
gameInput = input.next();
if(gameInput.equals("exit"))
{
System.out.println("Program will now end. Goodbye.");
inputLoop = false;
input.close();
}
gameNumber = Integer.parseInt(gameInput);
if(gameNumber >= 20001 && gameNumber <= 21230)
{
System.out.println("You have inputted a valid game number.");
inputLoop = false;
input.close();
}
}
catch(NumberFormatException e)
{
if(!gameInput.equals("exit"))
{
System.err.println("Invalid game number. Please try again.");
}
}
}
}
}
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.
The program takes user input which is supposed to be an integer greater than 0. If the user doesn't do this he is notified of the mistake and is reprompted. Once the correct input is entered, the value is returned. What's the best way to do this? The following code is my try but doesn't work. It seems unnecessarily complex for such an easy task.
System.out.println("Please enter an integer greater than 0:");
Scanner scan = new Scanner(System.in);
int red = -1;
do
{
try
{
red = scan.nextInt();
}catch(InputMismatchException e)
{
System.out.println("Number must be an integer");
scan.nextLine();
if(red < 1)
System.out.println("Number must be more than zero");
else
break;
}
}while(true);
return red;
Sometimes I don't know what to put in my question because I already know the code doesn't work - so if there's something else I should tell please let me know.
The basic concept is running in the right direction, beware though, nextInt won't consume the new line, leaving it within the scanner, meaning you will end up with an infinite loop after the first unsuccessful loop.
Personally, I would simply get the input as a String using nextLine, which will consume the new line, causing the next loop to stop at the statement.
Then I would simply parse the String to an int value using Integer.parseInt
For example...
Scanner scan = new Scanner(System.in);
int red = -1;
do {
System.out.print("Please enter an integer greater than 0:");
String text = scan.nextLine();
if (text != null && !text.isEmpty()) {
try {
red = Integer.parseInt(text);
// This is optional...
if (red < 1) {
System.out.println("Number must be more than zero");
}
} catch (NumberFormatException exp) {
// This is optional...
System.out.println("Not a number, try again...");
}
}
} while (red < 1);
I use this class instead of the Scanner or BufferedReader classes to get user input:
import java.io.*;
public class Input{
private static BufferedReader input=new BufferedReader
(new InputStreamReader(System.in));
public static Double getDouble(String prompt){
Double value;
System.out.print(prompt);
try{
value=Double.parseDouble(Input.input.readLine());
}
catch (Exception error){
// error condition
value=null;
}
return value;
}
public static Integer getInteger(String prompt){
Integer value;
System.out.print(prompt);
try{
value=Integer.parseInt(Input.input.readLine());
}
catch (Exception error){
// error condition
value=null;
}
return value;
}
public static String getString(String prompt){
String string;
System.out.print(prompt);
try{
string=Input.input.readLine();
}
catch (Exception error){
// error condition
string=null;
}
return string;
}
}
Now, to answer your question u can write your code like this:
public class InputTest {
public int checkValue() {
int value;
do {
value = Input.getInteger("Enter a value greater than 0: ");
} while (value <= 0);
return value;
}
}