Original Question
For the following small code I'm getting the error...
import java.io.*;
class test
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int i;
System.out.println("Enter no of processes ");
int no_of_process=Integer.parseInt(br.readLine());
int process[]=new int[no_of_process];
System.out.println("Enter the values");
for(i=0;i<no_of_process;i++)
process[i]=Integer.parseInt(br.readLine());
for(i=0;i<no_of_process;i++)
System.out.println(process[i]);
}
}
Input:
Enter no of processes
5
Enter the values
1
2
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Integer.parseInt(Integer.java:470)
at java.lang.Integer.parseInt(Integer.java:499)
at test.main(test.java:17)
Process completed.
I think I have written the code properly and proper integer input is also given. How do I get rid of the above error without using any explicit exception handling statements?
Further Question:
Thanks guys for your answers...it is working. But there is one new question in my mind.
I tried the following modification in the code and executed it. To my surprise, input was accepted properly without any run time error.
for(i=0;i<no_of_process;i++)
{
System.out.println(Write anything or even keep it blank);
process[i]=Integer.parseInt(br.readLine());
}
By adding just one Print statement before (or even after) the input statement in the for loop, my program worked correctly and no exception was thrown while giving input.
Can you guys explain the reason behind this?
Again if I remove the Print statement from there, the same error gets repeated. I am really confused about the reason behind this. Please help.
Without any error handling statements? check to see if br.readLine() is returning "" before you attempt to parse it, like so:
String line = br.readLine();
if(!String.isEmpty(line))
{
//Do stuff
}
else
{
//Do other stuff
}
How to get rid of above error without using any explicit exception handling statements?
for (i = 0; i < no_of_process; i++) {
String input;
do {
input = br.readLine();
if (isInteger(input)) {
process[i]=Integer.parseInt(input);
} else {
//error handling here
System.err.println("you entered an invalid input");
}
} while(isInteger(input));
}
And isIntegerlooks like this:
public static boolean isInteger(String s)
{
try {
Integer.parseInt(s);
}
catch (Exception e) {
return false;
}
return true;
}
I think I have written properly and proper integer input is also given.
I think not ;) i think you pressed the return with out typing anything
Try this:
import java.io.*;
public class test
{
public static void main(String args[]) throws IOException
{
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
int i;
System.out.println("Enter no of processes ");
try{
int no_of_process=Integer.parseInt(br.readLine());
int process[]=new int[no_of_process];
System.out.println("Enter the values");
for(i=0;i<no_of_process;i++)
process[i]=Integer.parseInt(br.readLine());
for(i=0;i<no_of_process;i++)
System.out.println(process[i]);
}
catch(NumberFormatException n)
{
System.out.println(n.getMessage());
}
}
}
Related
I'm trying to write a getInt() method, which abstracts the extraction of an integer from the console, to the rest of my program.
Inside, is a try using resource -- the resource being a scanner; with a catch block for the inevitable InputMismatchException.
It captures valid inputs, fine; and catches false inputs.
However, after -- recursively -- trying to again capture the input, my scanner instantly throws a NoSuchElementException, which is obviously linked to the last mismatch error.
Do I need to clear something in the second scanner, perhaps left from the first?
private static int getInt(String name) {
try (Scanner scanner = new Scanner(System.in)) {
System.out.printf("Enter %s: ", name);
return scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid");
return getInt(name);
}
}
I already tried to instantiate the scanner out of the function, like so:
Scanner scanner = new Scanner(System.in);
getInt(scanner, name);
...
private static int getInt(Scanner scanner, String name) {
try {
System.out.printf("Enter %s: ", name);
return scanner.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid");
return getInt(scanner, name);
}
}
Here, I simply get a stack over flow error, because the mismatch error recurs.
Can someone explain and help me fix this program.
import java.util.*;
import java.io.*;
public class test {
public static void main(String[] args) {
Scanner key = new Scanner(System.in);
boolean clear;
int in = 0;
do {
clear = true;
try {
in = key.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid");
clear = false;
}
} while (clear == false);
String stringIn = Integer.toString(in);
String[] dec = stringIn.split("");
for (int i = 1; i < (dec.length); i++) {
System.out.print(dec[i] + " ");
}
}
}
Whenever I enter a invalid input instead of an int, my program keeps looping "Invalid" instead of giving the option to enter a new value for in.
The problem is that if the scanner fails to find an input in the correct format, it will throw an exception and not read the input.
Because the scanner does not read the invalid int input, the next time nextInt is called, it will try to read the invalid input again, and miserably fails at it, printing another "invalid!"
So you need to read the input afterwards if it finds an invalid int:
// do this in the catch block:
key.next();
This makes sure that the next token is read.
Full code:
Scanner key = new Scanner(System.in);
boolean clear;
int in = 0;
do {
clear = true;
try {
in = key.nextInt();
} catch (InputMismatchException e) {
System.out.println("Invalid");
clear = false;
key.next();
}
} while (clear == false);
String stringIn = Integer.toString(in);
String[] dec = stringIn.split("");
for (int i = 1; i < (dec.length); i++) {
System.out.print(dec[i] + " ");
}
Check the API of the nextInt method:
This method will throw InputMismatchException if the next token cannot be translated into a valid int value as described below. If the translation is successful, the scanner advances past the input that matched.
Meaning, that if it's not successful - it will not advance and will try to execute nextInt over the illegal token over and over again failing every time.
Try adding next() into the exception catch clause, it should skip the token and read the next one then. next() reads a String, so it does not really care about the formatting, and will allow you to advance the position in the stream to read the next token.
The problem is that you are writing to the console inside the catch, so then when you call key.nextInt() in the try the program reads the value you print to the console, so an easy way to solve this is to add a line like: key.nextLine() inside the catch and that will solve your problem.
For my team's programming project, we have a board game, where the user has various inputs at different stages.
When the user wants to quit in the middle of the game, we want the user to press Control+D (which throws the NoSuchElementException) which I want to propagate back to the main menu to allow the user to begin a new game without re-running the program.
I run into problems when I try to access any Scanner .next* methods - it throws the same exception with "No line found". As I read somewhere, the EOF makes hasNext* return false.
The EOF completely stops the Scanner, and any new Scanner from working, as I get the same problem. So, the EOF works exactly as I want it to, until we ask for more input from the user.
(I have done this in C successfully)
import java.util.Scanner;
public class Main {
public static void main(String[] args)
{
boolean run = true;
String str;
Scanner scan1 = new Scanner(System.in);
while (run)
{
try
{
System.out.println(scan1.hasNextLine());
str = scan1.nextLine();
System.out.println(str);
}
catch (Exception e)
{
System.out.println("Error");
//scan1.nextLine(); // this throws the "No line found"
run = false;
}
}
Scanner scan2 = new Scanner(System.in);
System.out.println(scan2.next()); // without scan1, this throws the "NoSuchElementException"
}
}
Any ideas on how to continue Scanning after we EOF?
The following method causes a No line found Exception:
private static String getRebaseAnswer(boolean isFirst, boolean isLast) {
System.out.println("Would you like to (c)ontinue, (s)kip this commit, or"
+ " change this commit's (m)essage?");
Scanner in = new Scanner(System.in);
String answer;
while (true) {
answer = in.nextLine(); // <--- This Line
if (answer.equals("c") || answer.equals("m")) {
in.close();
return answer;
} else if (answer.equals("s") && !isFirst && !isLast) {
in.close();
return answer;
} else {
System.out.println("Would you like to (c)ontinue, (s)kip this commit, or"
+ " change this commit's (m)essage?");
}
}
}
I am calling the method in this method:
...
String answer;
Scanner in;
currHead = branchHeads.get(arg);
while (toRebase != null) {
System.out.println("Currently replaying:");
toRebase.getNode().printInfo();
answer = getRebaseAnswer(isFirst, toRebase.getParent() == null); // <--- This Line
...
What is causing the error?? Shouldn't the scanner wait for me to input a line before continuing the getRebaseAnswer method? A different method in my code has the exact same structure as the above method and encounters no problems. I've checked multiple other posts about this problem but their suggestions are all not pertinent to this problem or do not solve it.
This method runs with no problems:
private static boolean handleDangerous() {
System.out.println("Warning: The command you entered may alter the files in your"
+ " working directory. Uncommitted changes may be lost. Are you sure you"
+ " want to continue? (yes/no)");
Scanner in = new Scanner(System.in);
String answer;
while (true) {
answer = in.nextLine();
if (answer.equals("yes")) {
in.close();
return true;
} else if (answer.equals("no")) {
in.close();
return false;
} else {
System.out.println("Not a valid answer, please enter (yes/no).");
}
}
}
When you create a scanner connected to System.in and close it, you also close System.in. Therefore, subsequent attempts to read from System.in will result in the exception you observe.
The way is avoid this is to create the Scanner only once, and never close it until your program is finished. This Scanner should be passed to whichever function needs to read from System.in.
don't close scanner otherwise Stream will also be closed.
in.close();
remove this line from current location and put it in main method at the end so after all the operation stream will be closed..
You might be calling some other method which have already closed the stream and then you are calling this method.
I am wondering if the first way to throw an IOException is the better way to do this,
Like this , but I can't trigger an IOException to test it.
public static String inputStr (String prompt) throws IOException
{
String inputStr = "";
System.out.print(prompt);
inputStr = stdin.readLine();
if (inputStr.length() == 0)
{
System.out.println("Error! Enter valid field!");
inputStr(prompt);
}
return inputStr;
}
Or within the method.
public static String inputStr (String prompt)
{
String inputStr = "";
System.out.print(prompt);
try
{
inputStr = stdin.readLine();
if (inputStr.length() == 0)
{
System.out.println("Error! Enter valid field!");
inputStr(prompt);
}
} catch (IOException e)
{
System.out.println("Error! Enter valid field!");
inputStr(prompt);
}
return inputStr;
}
Is it necessary to include a customised message in case one is thrown? Re this question Java - What throws an IOException I am unable to test for what will happen.
Not sure if this should be codereview, as I am unsure if it actually will work.
If stdin.readLine() throws an IOException, trying to re-read again from stdin won't succeed: you'll get another IOException, making your second snippet go into an infinite recursive loop, ending with a StackOverflowError.
You can trigger an IOException to test. Just added this in your if statement:
throw new IOException("Testing Failure");
As far as how you deal with the exception it really depends on if you want the current method to deal with it or if you just want to pass it to whatever called the method.