hasNextInt() From Scanner behaving weirdly - java

I have a very simple loop that waits for a number (int) and as long as that number is not exitOption it does not leave the loop, however I get an unexpected error, and I don't know what's causing it.
Edit
Adding another snippet so you can compile
public static void main(String[] args) throws FileNotFoundException,
SecurityException,
IOException,
ClassNotFoundException {
while (controller.selectOptionMM());
/Edit
public boolean selectOptionMM() throws SecurityException,
FileNotFoundException,
IOException {
int cmd = ui.getExitOption();
ui.mainMenu();
cmd = utils.readInteger(">>> "); // this is my problem, right here
// code in next snippet
while (cmd <1 || cmd > ui.getExitOption()) {
System.out.println("Invalid command!");
cmd = utils.readInteger(">>> ");
}
switch (cmd) {
case 1:
case 2:
case 3:
case 4: this.repository.close();
return true;
case 5: return false;
}
return false;
}
Here is what fails:
public int readInteger(String cmdPrompt) {
int cmd = 0;
Scanner input = new Scanner(System.in);
System.out.printf(cmdPrompt);
try {
if (input.hasNextInt())
cmd = input.nextInt(); // first time it works
// Second time it does not allow me to input anything
// catches InputMissmatchException, does not print message
// for said catch
// infinitely prints "Invalid command" from previous snippet
} catch (InputMismatchException ime) {
System.out.println("InputMismatchException: " + ime);
} catch (NoSuchElementException nsee) {
System.out.println("NoSuchElementException: " + nsee);
} catch (IllegalStateException ise) {
} finally {
input.close(); // not sure if I should test with if (input != null) THEN close
}
return cmd;
}
First time I pass trough, it reads the number no problem. Now if the number is not 5 (in this case exitOption), it passes again trough readInteger(String cmdPrompt) except this time it jumps to catch (InputMismatchException ime) (debug) except it does not print that message and just jumps to Error, input must be number and Invalid command.
Is something stuck in my input buffer, can I flush it, why is it (input buffer) stuck (with random data)???
I'll try debugging again and see what's stuck in my input buffer, if I can figure out how to see that.

The problem is in the call to input.close() - this causes the underlying input stream to be closed. When the input stream being closed is System.in, bad things happen (namely, you can't read from stdin any more). You should be OK just eliminating this line.

input.hasNextInt()
This line throws the exception if there is no Integer, so instead of it going to else block it forward to catch block. It will never go to else block if exception get caught.

Related

Scanner does not read user input once the thread throws an exception in Java [duplicate]

This question already has answers here:
How to use Scanner to accept only valid int as input
(6 answers)
Closed 2 years ago.
I have a separate thread class and below is the run method,
#Override
public void run() {
Scanner scanner = new Scanner(System.in);
int iRequestType = 0;
int iRequestId = 0;
while (!exit){
try {
System.out.print("\nRealTime - 1\nHttpUrl - 2\nSelect one : ");
iRequestType = scanner.nextInt(); //it will wait here after the exception occurs
System.out.print("\nEnter Request ID : ");
iRequestId = scanner.nextInt();
if(iRequestType == 1 && !map_RealTimeRequests.isEmpty()){
sendRealTimeRequest(iRequestId);
} else if (iRequestType == 2 && !map_HttpUrlRequests.isEmpty()){
sendHttpUrlRequest(iRequestId);
} else if(iRequestType > 2) {
System.out.println("Invalid List Number");
}else {
System.out.println("Empty List");
}
} catch (InputMismatchException e){
System.out.println("Invalid request type or ID : " + e);
scanner.close();
scanner = new Scanner(System.in);
}
}
}
If I enter numbers, the program works fine. When I enter a character, it goes to the catch block and and execute the lines within it as expected. Once the execution of catch block completes, it will iterate again and ask for the keyboard inputs. But when I try to enter a value (a number or a character), it does not read anything and keep waiting without executing the next lines.
What I want to do is, ask the user to enter a number and if the user enter a character, print an error message in console and iterate the while loop again. How can I solve this issue? Thanks in advance!
You should not call scanner.close() because that closes System.in. You don't want to close System.in you just want to clear out the buffer. You can do that by replacing the scanner as you did (without the close() call), or you can call nextLine() if it's single-line input like this:
} catch (InputMismatchException e){
System.out.println("Invalid request type or ID : " + e);
scanner.nextLine();
}

Trying to use Thread.sleep function, catch token has multiple errors

import java.util.Scanner;
public class HelloWorld
{
public static void main(String[] args)
{
Scanner math = new Scanner(System.in);
System.out.println("What is 2 + 2?");
int num = math.nextInt();
System.out.println("Wrong."); // Displays "Wrong." no matter the answer.
{
Thread.sleep(2000); // Adds a timer for 2 seconds.
}
catch(InterruptedException e)
{
System.out.println("Please, try again :-)");
}
int num1 = math.nextInt();
System.out.println(""); //Displays some message.
}
}
The code is supposed to display "What is 2 + 2?", a user inputs an answer, the code returns "Wrong." no matter what the answer. After a 2 second pause, the code displays "Please, try again :-)" and a user inputs an integer and the code returns a message.
The errors occur on the line with the catch token. The errors are:
Syntax error on token "catch", ( expected,
Syntax error, insert "-> LambdaBody" to complete LambdaExpression,
Syntax error, insert "AssignmentOperator Expression" to complete Assignment,
Syntax error, insert ";" to complete Statement
To use a catch in java you need to have a try. It is called a try..catch block. Please read the documentation here
So, adding a try as follows should get rid of the errors you are asking about here :
System.out.println("Wrong."); // Displays "Wrong." no matter the answer.
try // Looks like you missed the try here
{
Thread.sleep(2000); // Adds a timer for 2 seconds.
} catch (InterruptedException e) {
System.out.println("Please, try again :-)");
}
I cant see try block. you can use this way also without try catch. Main method can throw InterruptedException ...
public class HelloWorld {
public static void main(String[] args) throws InterruptedException {
Scanner math = new Scanner(System.in);
System.out.println("What is 2 + 2?");
int num = math.nextInt();
System.out.println("Wrong."); // Displays "Wrong." no matter the answer.
{
Thread.sleep(2000); // Adds a timer for 2 seconds.
}
int num1 = math.nextInt();
System.out.println(""); //Displays some message.
}
}

VM Terminated on static method

public static void main() {
String fileName = "cardNumbers.txt";
String line = null;
try {
FileReader fileReader = new FileReader(fileName);
BufferedReader bufferedReader = new BufferedReader(fileReader);
while((line = bufferedReader.readLine()) != null)
{
CreditCard card = new CreditCard(line);
if (card.creditCardType().equalsIgnoreCase("Unknown"))
{
System.out.println("Card number " + card.getCardNumber() + "is an unknown credit card type.");
}
else if (card.isValid())
{
System.out.println(card.creditCardType() + " number" + card.getCardNumber() + " is valid.");
}
else if (!card.isValid())
{
System.out.println(card.creditCardType() + " number " + card.getCardNumber() + " is not valid.");
}
}
}
catch (FileNotFoundException ex)
{
System.out.println("file not found exception thrown");
}
catch (IOException ex)
{
System.out.println("error while reading the file");
}
finally
{
System.exit(0);
}
}
When I run this method it just says ProcessCardNumbers.main(); VM Terminated. Instead of actually printing out the content.
If I add a print at the very start of the function or in the finally block, they are printed.
Im not sure why this is happening or how I can fix it.
As you told us that:
Adding a println at the start is printed
and
Adding a println in the finally works too
we can deduce that your code is working. It's just that when you reach while((line = bufferedReader.readLine()) != null), line stays null, so you never enter your while.
Why is that? Well, your file may be empty to begin with. If it is not, double-check the encoding of your file: it may not be using the proper returns symbols, hence not having a "completed line".
This seems that in your text file cardNumbers.txt has no data. When this program will execute within while loop bufferedReader.readLine()). will return null. So loop will terminate. After termination you have written System.exit(0); function in finally block which terminate JVM on the spot. So JVM is terminated now that's why you are not able to see anything after working of this code.
If you want to check working, write one SOP statement in finally block. Probably that will execute without termination of JVM.
The problem here is not the bug in your code but the design problem that does not let you see the bug.
You are probably getting an undeclared exception (RuntimeException) and the VM can't print it because you kill it before in the finally.
You have several options:
Remove the System.exit(0); and let it die normally. This may fail if there is another non-daemon thread running. You may try to stop it. You can, for example, cancel a Timer.
Add a catch (RuntimeException e) { section before the finally and print the captured error. e.printStackTrace(); should do the trick.
With any of those you should see the exception on console so you can fix it.
Your main method signature must look like this:
public static void main(String[] args)
instead of
public static void main()

How to reprompt for invalid Boolean input (java)

When I run the program if I type something other than "true" or "false" it throws a InputMismatchException.
do {
System.out.print("Do passengers have an individual tv screen?"
+ "(true OR false): ");
hasVideo = keyboard.nextBoolean();
bus.setIndividualVideo(hasVideo);
} while (!(hasVideo == true) && !(hasVideo == false));
Catch the error and treat it as a invalid response...
try {
System.out.print("Do passengers have an individual tv screen?"
+ "(true OR false): ");
hasVideo = keyboard.nextBoolean();
} catch (InputMismatchException exp) {
System.err.println("Please, enter only true or false");
}
Take a look at The try Block for more details
Aha, time to learn about Exception handling! Any of the Exception types that you see when java crashes can in fact be caught inside the program with a try-catch block.
try {
// code that might throw exceptions 1
// code that might throw exceptions 2
} catch (Exception e) {
// do something to fix the error
}
If any code in the try{ } part does throw an Exception then it will immediately skip to the catch( ) { } part, skipping any other statements in the try{ }.
Your code with a try-catch would look like:
boolean loopAgain = false;
do {
try {
System.out.print("Do passengers have an individual tv screen?"
+ "(true OR false): ");
hasVideo = keyboard.nextBoolean();
bus.setIndividualVideo(hasVideo);
loopAgain = false;
} catch (InputMismatchException e) {
System.err.println("Please, enter only true or false");
loopAgain = true;
}
} while (loopAgain);
Edit: I borrowed the println("Please, enter only true or false"); from #MadProgrammer's answer.
You have to prompt the user to enter a Boolean value. Because nextBoolean() can throw an exception, the best thing to do is to put that code inside a try/catch. The catch block code is only executed if anything other than true or false is entered. You can add a while() or do/while() loop to keep telling the user to try again. However, the most important thing to do in the catch block is to flush the input stream. Remember, even though there was an exception, the stream still contains stuff in it. It has to be properly consumed before using again. The code below should do exactly what you are looking for:
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
Boolean answer = null;
do
{
System.out.println("Enter either true or false");
try
{
answer = input.nextBoolean();
}
catch(InputMismatchException e)
{
System.out.println("ERROR: The input provided is not a valid boolean value. Try again...");
input.next(); // flush the stream
}
} while(answer == null);
input.close();
}

Run Jar file with more than one argument

I am building an optimization into a JPEG-Encoder written in Java. To do my benchmark i want to extract the orginal code and the optimized code into separated jars. Each jar has to take two arguments. The first on for the file name and the secound for the repeat of the compression of the jpeg.
public static void main(String[] args) {
String filepath = args[0];
try {
int times = Integer.getInteger(args[1]);
runBenchmark(filepath, times);
} catch(IOException | NumberFormatException ioe) {
System.out.println("Your arguments are Wrong! Use the follow order!");
System.out.println("1. Argument must be the filename of the image.");
System.out.println("2. Argument must be a number to repeat the compression.");
}
}
This is my main, witch handle my args. I cant run the arguments on IntellJ . Even if I compile it the a jar, i cant pass my arg2.
I passed two arguments via configuration in intellj and i get a NullPointerException. So i tried to figure out if my java can take two arguments. I wrote a simple main in vim and compiled ran it with two args and worked. I repeated this in a new Project in intellj.
This is working. But why?
You have to check if the parameter is a int or not.
Use Integer.parseInt() and a try-catch block to inform the user if a failure happen.
int times = 0;
try {
times = Integer.parseInt(args[1]);
} catch (Exception e) {
System.out.println("failure with a parameter");
}
I changed the method to Integer.parseInt(string) and now it works. It was the Integer.getInt() it . I thought i had now 2. arg because I get the NullPointerException.
Now it work with this code.
public static void main(String[] args) {
try {
String filepath = args[0];
int times = Integer.parseInt(args[1]);
runBenchmark(filepath, times);
} catch (NumberFormatException nfe) {
System.out.println("2. Arg must be an number");
} catch (IOException ioe) {
System.out.println("File not found.");
} catch(Exception e) {
System.out.println("Your arguments are Wrong! Use the follow order!");
System.out.println("1. Argument must be the filename of the image.");
System.out.println("2. Argument must be a number to repeat the compression.");
}
}

Categories