Everytime I run this code, the console goes into an infinite loop printing "Please input a number". I do not understand why this is happening. Thanks in advance.
boolean check = true;
int temp = 0;
while(check==true){
try{
temp= asker.nextInt();
check = false;
}
catch(InputMismatchException e){
System.out.println("Please input a number.");
}
}
Edit: asker is a Scanner. The purpose of the code is to loop until an integer is inputted by the user.
The method asker.NextInt() is throwing an InputMismatchException, indicating that the input received from asker (assuming it's a Scanner) isn't actually an integer. This exception causes the loop to restart without setting check to false.
Print the exception within the catch block to get more information about the failure. But most likely, you're feeding your application something (lots and lots of something, if it's looping like that) that doesn't actually contain integer values.
You never want to actually "Use" try/catch--by that I mean don't use it as part of your program logic--this is what you are doing.
One big problem is that, like your app, you don't see the stack trace. Eating a stack trace in an exception is almost always wrong.
If you do have to catch an exception, handle it near the catch as well as you can, but it's better to set up your code so that the exception can't be thrown anyway.
Discard this advice if your teacher told you to do it this way, but remember in the back of your mind that it's poor form.
Also don't tell your teacher that it's poor form :) he either doesn't know in which case he won't understand why or he does know and is using this to show you how try/catch works.
What is asker, a Scanner? If nextInt() fails, it doesn't consume any input, so when you catch your exception and loop back around to try again, it ends up just reading the same bad input again.
You should do something in the catch block to consume the invalid input, so that the next time around, it can read some different input. Call asker.nextLine() maybe, and ignore the return value.
You need to break the loop and report why the loop occurs
boolean NotValid = true;
int temp = 0;
while(NotValid){
try{
temp= asker.nextInt();
NotValid = false;
break; // stop
}
catch(InputMismatchException e){
System.out.println("Please input a number. reason why:");
System.out.println(e);
NotValid = true;
}
}
Related
This is a part of a program I'm making for practice, its purpose doesn't really matter.
I have declared the Scanner as a field of the class** (it's not written here sorry).
I want to make a method that returns an answer specified to the users input. And I want to make all the neccesary checks needed so the user can't input a character or symbol, just an integer. When the input data is of the wrong type I want the user to try input again.
public static void Answer() {
System.out.println("\n\t1.It was good! \n\t2.Kinda bad too...");
System.out.println();
if (scanner.hasNextInt()) {
int choice = scanner.nextInt();
switch (choice) {
case 1:
System.out.println("Oh great!");
break;
case 2:
System.out.println("I see you as well");
break;
default:
System.out.println("Please select a valid answer :");
Answer();
break;
} else {
System.out.println("Please select a number, characters are not acceptable!");
Answer();
}
When I enter an invalid number like 3,4 etc the algorithm triggers the switch block and the recursive call as well, working just fine!
BUT when I enter a character it triggers an infinite recursive call without letting me enter new input form the scanner and ends up in StackOverflow error.
You check if the Scanner has an int. If it does not, then it goes to the else branch.
In the else branch, it calls Answer() again. But here's the catch: your scanner still doesn't have an int. So scanner.hasNextInt() returns false. hasNextInt() does not try to read anything - it merely checks if there is input that can be interpreted as an int.
(Source: Java documentation).
So the program goes again to the else branch, without ever reaching the point where it can try to read input... and there it calls Answer() again. Now, the code still doesn't have an int... so once again, scanner.hasNextInt() returns false, and it goes to the else branch. Once again, it does not get to the part where the scanner consumes input, but instead gets to the part where it calls Answer() again...
And this will continue, until the call stack is full and you get the StackOverflow error.
You'll have to take care of the situation that the user enters something that is not an int. You'll have to consume that input that is not an int.
As an aside, I'd prefer to do this using iteration, rather than recursion.
I'm trying to create a program that keeps asking a question until the user presses enter. But for some reason, the program goes into an infinite loop that continuously outputs:
"Enter the operation: You need to add '[' at the beginning of the set."
If you accidentally do not follow the rules. Now, the program should print that message but only once. I think the loop continuously asks for the operation but it goes straight to the error (If you do not enter anything, I guess that counts as not using an [ at the beginning).
I already know how to solve it but because I tried everything!! I am not sure how my solution changes anything... Can you give me advice on how to solve it and/or explain to me what is it about the do-while loop implemented at the end that does the trick?
Edit: TextIO is a class written by Eck, D. J. in his book. I will link the chapter where it gives the code here: http://math.hws.edu/javanotes/c2/s6.html
The problematic code is
while (true) {
System.out.print("\nEnter the operation: ");
TextIO.skipBlanks();
if (TextIO.peek() == '\n') { //There is no operation, end the program.
break;
}
try {
calculation();
}
catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
}
The solution I implemented looks like this:
while (true) {
System.out.print("\nEnter the operation: ");
TextIO.skipBlanks();
if (TextIO.peek() == '\n') { //There is no operation, end the program.
break;
}
try {
calculation();
}
catch (IllegalArgumentException e) {
System.out.println(e.getMessage());
}
do {
ch = TextIO.getAnyChar(); // Read ahead the "enter".
} while (ch != '\n'); //If necessary, make sure to stop the error message and keep the loop going.
}
Thanks, guys!!
It sounds like you're using TextIO class from David J. Eck's Introduction to Programming Using Java, Eighth Edition book.
According to the source of the class:
[TextIO.peek()] returns the next character in the current input source, without actually removing that character from the input.
You're checking the input actually without removing it. That's why in the next iteration, the loop keeps reading the same bad input, and throwing the exception indefinitely.
Also your fix performs what is lacking after calling peek(). Removing the char from the input.
Hence, replacing peek() by getAnyChar() in your first attempt solves the problem.
I'm not sure what's TextIO, you should use the standard Scanner class.
Code:
Scanner input;
File file = new File("Latex3.bib");
input = new Scanner(file);
input.useDelimiter("#ARTICLE");
while(input.hasNext()) {
System.out.println("It should not print this");
s = input.next();
System.out.println("Token"+c+": "+s);
c++;
author = s.substring
(s.indexOf("author={")+8,
s.indexOf("}", s.indexOf("author={")+8));
System.out.println("Authors for this ARTICLE: "+author);
System.out.println();
}
(in the code, c is an int that I declared earlier in the original code for just counting and increasing by each loop).
I was getting weird exception from the code that I think it should not throw. After testing each input files, it turns out my while loop runs even when there's no "#ARTICLE" in the Latex3.bib file.
As far as I know, if the file does not have "#ARTICLE", that means that input does not get any token. So from the beginning, its hasNext() should return false. But it just wasn't.
The part what I think funny and strange is: if Latex3.bib is completely empty(not even one space bar or enter), the while loop or whatever reads it as an empty file, therefore no token is given to input.
However, if Latex3.bib has like 1~3 linebreak(enters), then that while loop runs. I have no idea why this is happening. I am suspecting that Scanner.useDelimiter(pattern) does not affect or at least cooperate perfectly with other Scanner methods like hasNext(), although I believe this won't be the real case because it's a very crucial functionality.
edit:
Just to be clear what exception I got, the StringIndexOutOfBoundsException was thrown at the point of assigning author(String). Well it's obvious because the file was empty... and there was nothing to substring or find index..
Why does it continue in the while loop repeating "Please enter a valid number" and it keeps repeating without stopping to let the user input something.
while (true) { //This will continually run until something is returned, AkA the number 1 or 2
Scanner s = new Scanner(System.in);
try {
input = s.nextInt();
} catch (Exception e) {
System.out.println("Please enter a valid number!");
}
s.close();
}
When I use the debugger nothing seems to be the cause of this problem and no errors are thrown. What is causing this problem and how can it be fixed?
Closing a scanner also closes the underlying stream if it implements the Closable interface.
That's System.in in this case and, once closed, you won't be able to create a scanner using it again.
See http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#close() for the gritty detail.
But, even if you fix that problem, an exception from nextInt will not advance the stream pointer so, the next time you call it, it will find exactly the same data in the input stream again.
You need to clear out the erroneous data before trying again. Since you're accepting user input, one solution is to call nextLine and throw that away;
string junk = s.nextLine();
Remove
s.close();
And Define your Scanner object outside the while loop as it not an Issue. Btw, I've tried your code, it worked fine until I entered a input which is not an int. When I entered a string, the exception sysout statement keeps printing infinitely
So you've to add
string junk = s.nextLine();
in your Exception block like paxdiablo said so that it wont repeat continuously.
please help me, i know its too easy but i cant answer it, waaah, i think i have an headache now, the problem was:
Prompt the user for a message and ask how many times to print it.
your program output should be as follows:
How will you like me to print?
How many times do you want me to print it?
and my prof told us that we should use JOptionPane and control structure for the two question, and the answer should be in System.out.println..
please help me, thank you,
Start by taking a look at How to Make Dialogs.
You will want to use JOptionPane#showInputDialog to get the information from the user, you will need to do this (at least) twice, once to get the message and once to the count.
You could use a do-while to ensure that the user enters a valid, numerical value...
int count = 0;
do {
String input = JOptionPane.showInputDialog(...);
try {
count = Integer.parseInt(input);
} catch (NumberFormatException exp) {
// You could show a JOptionPane.showMessageDialog here as an error message
}
} while (count != 0);
Once you have all the information, you will could use a for-loop to print the result...
Take a look at:
JOptionPane Java Docs
The for Statement
For more details