I have something like this:
Scanner in=new Scanner(System.in);
int rounds = 0;
while (rounds < 1 || rounds > 3) {
System.out.print("How many rounds? ");
if (in.hasNextInt()) {
rounds = in.nextInt();
} else {
System.out.println("Invalid input. Please try again.");
System.out.println();
}
// Clear buffer
}
System.out.print(rounds+" rounds.");
How can I clear the buffer?
Edit: I tried the following, but it does not work for some reason:
while(in.hasNext())
in.next();
Try this:
in.nextLine();
This advances the Scanner to the next line.
You can't explicitly clear Scanner's buffer. Internally, it may clear the buffer after a token is read, but that's an implementation detail outside of the porgrammers' reach.
Use the following command:
in.nextLine();
right after
System.out.println("Invalid input. Please Try Again.");
System.out.println();
or after the following curly bracket (where your comment regarding it, is).
This command advances the scanner to the next line (when reading from a file or string, this simply reads the next line), thus essentially flushing it, in this case. It clears the buffer and readies the scanner for a new input. It can, preferably, be used for clearing the current buffer when a user has entered an invalid input (such as a letter when asked for a number).
Documentation of the method can be found here:
http://docs.oracle.com/javase/7/docs/api/java/util/Scanner.html#nextLine()
Hope this helps!
This should fix it...
Scanner in=new Scanner(System.in);
int rounds = 0;
while (rounds < 1 || rounds > 3) {
System.out.print("How many rounds? ");
if (in.hasNextInt()) {
rounds = in.nextInt();
} else {
System.out.println("Invalid input. Please try again.");
in.next(); // -->important
System.out.println();
}
// Clear buffer
}
System.out.print(rounds+" rounds.");
Other people have suggested using in.nextLine() to clear the buffer, which works for single-line input. As comments point out, however, sometimes System.in input can be multi-line.
You can instead create a new Scanner object where you want to clear the buffer if you are using System.in and not some other InputStream.
in = new Scanner(System.in);
If you do this, don't call in.close() first. Doing so will close System.in, and so you will get NoSuchElementExceptions on subsequent calls to in.nextInt(); System.in probably shouldn't be closed during your program.
(The above approach is specific to System.in. It might not be appropriate for other input streams.)
If you really need to close your Scanner object before creating a new one, this StackOverflow answer suggests creating an InputStream wrapper for System.in that has its own close() method that doesn't close the wrapped System.in stream. This is overkill for simple programs, though.
scan.nextLine();
Put the above line before reading String input
Related
This is the program
public class bInputMismathcExceptionDemo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean continueInput = true;
do {
try {
System.out.println("Enter an integer:");
int num = input.nextInt();
System.out.println("the number is " + num);
continueInput = false;
}
catch (InputMismatchException ex) {
System.out.println("Try again. (Incorrect input: an integer is required)");
}
input.nextLine();
}
while (continueInput);
}
}
I know nextInt() only read the integer not the "\n", but why should we need the input.nextLine() to read the "\n"? is it necessary?? because I think even without input.nextLine(), after it goes back to try {}, the input.nextInt() can still read the next integer I type, but in fact it is a infinite loop.
I still don't know the logic behind it, hope someone can help me.
The reason it is necessary here is because of what happens when the input fails.
For example, try removing the input.nextLine() part, run the program again, and when it asks for input, enter abc and press Return
The result will be an infinite loop. Why?
Because nextInt() will try to read the incoming input. It will see that this input is not an integer, and will throw the exception. However, the input is not cleared. It will still be abc in the buffer. So going back to the loop will cause it to try parsing the same abc over and over.
Using nextLine() will clear the buffer, so that the next input you read after an error is going to be the fresh input that's after the bad line you have entered.
but why should we need the input.nextLine() to read the "\n"? is it necessary??
Yes (actually it's very common to do that), otherwise how will you consume the remaining \n? If you don't want to use nextLine to consume the left \n, use a different scanner object (I don't recommend this):
Scanner input1 = new Scanner(System.in);
Scanner input2 = new Scanner(System.in);
input1.nextInt();
input2.nextLine();
or use nextLine to read the integer value and convert it to int later so you won't have to consume the new line character later.
Also you can use:
input.nextInt();
input.skip("\\W*").nextLine();
or
input.skip("\n").nextLine();
if you need whitespaces before line
I have a client/server game where users take turns giving input to the game. I want anything a user types when it is not their turn to be ignored. I want to scan only the inputs the user gives after they are prompted. I am using java.util.Scanner for input, but I can't find a way to "flush" the scanner buffer without the program hanging. I also cannot find examples of other input reading methods doing what I want.
This is what I tried:
Scanner in = new Scanner(System.in);
//do game stuff
//I don't care about anything typed at this time
while(in.hasNextLine()){
in.nextLine();
}
System.out.println("Enter your move:");
String input = in.nextLine();
There is no way to disable a Scanner and re-enable it. Here are a few suggestions:
You can manually empty the Scanner before the player's turn like so (what (I think) you've been doing):
while(in.hasNext()) in.next();
Or, you can close the scanner at the end of the player's turn and instantiate a new one at the beginning of the next turn (you can't reopen a closed Scanner):
//Player's turn
//
//End of player's turn...
in.close();
//Beginning of player's turn
in = new Scanner(System.in);
This, however, will throw an IllegalStateException if you try to access the Scanner after it has been closed. To solve this, try (on Java 7 and later) the try-with-resources block:
//Overridden close method because you don't want to close System.in
try (Scanner in = new Scanner(new InputStreamReader(System.in)
{public void close() throws IOException {}})) {
System.out.println("Enter your move:");
String input = in.nextLine();
}
//End of player's turn
//Scanner is automatically closed and this code is out of the scanner's scope
I think this last option is your best bet. It restricts the scope of the Scanner to the relevant code, and it automates the instantiating/closing. Plus, it uses a (relatively) recent Java feature, so that might be the required answer to your problem.
I have a question regarding data validation and scanners.The following piece of code checks userinput.Anything other than an integer is not allowed and the user is asked to re-enter a value.My question is that the code works only if the scanner is declared within the while loop.The program executes infinitely if the scanner is declared outside.Why is that?Thanks.
int UserInp;
boolean dataType=false;
while(dataType==false)
{
Scanner sc=new Scanner(System.in);
try
{
System.out.print("\nEnter a number: ");
UserInp=sc.nextInt();
dataType=true;
}
catch(Exception JavaInputMismatch)
{
System.out.println("Option not available.Try again.");
}
}
Interesting problem!
What happens is that the Scanner attempts to translate the non-integer to an integer, and realizes it can't -- so it throws an InputMismatchException. However, it only advances past the token if the translation was successful.
Meaning, the invalid string is still in the input buffer, and it will fail the translation every single time you loop and try to call nextInt(). You never set dataType to true, and so you loop infinitely.
To see this in action, you can grab the arbitrary content in your catch block and print it out:
catch(Exception JavaInputMismatch){
System.out.println( sc.next() );
System.out.println("Option not available.Try again.");
}
Indeed, after invalid input, we get the following:
Enter a number: hello
hello
Option not available.Try again.
Enter a number:
And we don't loop infinitely. This is because the call to next() grabbed the value from the input buffer and advanced the scanner's pointer into that buffer to the next slot, which is now empty. So nextInt() will wait for input in that case.
Oh, and the reason it works fine if you initialize in the loop is that the scanner will always start reading input fresh; scanners don't share state across instances, so the "hello" that was in the buffer for the previous iteration isn't in the buffer for the next one due to the reinitialization.
Technically, it's still in the standard input buffer, but the scanner's pointer into that buffer is beyond the invalid string because it will start reading any new input, not existing input.
To add to Purag's answer, you could alternatively use nextLine() to advance the Scanner past the current line.
So your catch block will look like this:
catch(Exception JavaInputMismatch)
{
System.out.println("Option not available.Try again.");
sc.nextLine();
}
Tricky question.
You may get it!
The answer is simple. The Scanner object is kept live till the end of the execution as it is declared outside the while loop. Look this problem in the memory level.
The Scanner object is kept live so while entering the loop next time still the value(String value) will be there in Scanner object and it doesn't listens keyboard as the exception is already thrown.So the loop keeps going.
Note : The next() method in Scanner class will accept all the types of keyboard input but not the rest of the methods such as nextInt(), nextFloat() etc..,
I have been using the following code in c and c++ for looping till user feeds the correct value till the program comes out of it:
while((scanf("%d",&num)==1)//same way in for loop
{
//some code
}
Can i some how use the same way to accept and loop the program till i keep entering let's say an integer and floating or a char or a special character breaks it.
Use :
Scanner sc = new Scanner(System.in); // OR replace System.in with file to read
while(sc.hasNext()){
//code here
int x = sc.nextInt();
//...
}
There are different variants of hasNext() for specific expected input types: hasNextFloat(), hasNextInt()..
Same goes for next() method so you can find nextInt(), nextFloat() or even nextLine()
You can go to Java doc for more info.
As proposed in comments, you can use the Scanner class.
Note you need to read the in buffer with a nextLine() when it is not an int.
public static void main(String[] args) {
try (Scanner in = new Scanner(System.in)) {
System.out.println("Enter an int: ");
while (!in.hasNextInt()) {
System.out.println("That's not an int! try again...");
in.nextLine();
}
int myInt = in.nextInt();
System.out.println("You entered "+myInt);
}
}
This is the program
public class bInputMismathcExceptionDemo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
boolean continueInput = true;
do {
try {
System.out.println("Enter an integer:");
int num = input.nextInt();
System.out.println("the number is " + num);
continueInput = false;
}
catch (InputMismatchException ex) {
System.out.println("Try again. (Incorrect input: an integer is required)");
}
input.nextLine();
}
while (continueInput);
}
}
I know nextInt() only read the integer not the "\n", but why should we need the input.nextLine() to read the "\n"? is it necessary?? because I think even without input.nextLine(), after it goes back to try {}, the input.nextInt() can still read the next integer I type, but in fact it is a infinite loop.
I still don't know the logic behind it, hope someone can help me.
The reason it is necessary here is because of what happens when the input fails.
For example, try removing the input.nextLine() part, run the program again, and when it asks for input, enter abc and press Return
The result will be an infinite loop. Why?
Because nextInt() will try to read the incoming input. It will see that this input is not an integer, and will throw the exception. However, the input is not cleared. It will still be abc in the buffer. So going back to the loop will cause it to try parsing the same abc over and over.
Using nextLine() will clear the buffer, so that the next input you read after an error is going to be the fresh input that's after the bad line you have entered.
but why should we need the input.nextLine() to read the "\n"? is it necessary??
Yes (actually it's very common to do that), otherwise how will you consume the remaining \n? If you don't want to use nextLine to consume the left \n, use a different scanner object (I don't recommend this):
Scanner input1 = new Scanner(System.in);
Scanner input2 = new Scanner(System.in);
input1.nextInt();
input2.nextLine();
or use nextLine to read the integer value and convert it to int later so you won't have to consume the new line character later.
Also you can use:
input.nextInt();
input.skip("\\W*").nextLine();
or
input.skip("\n").nextLine();
if you need whitespaces before line