How to take single character input from user in Java? - java

In the below example , I am trying accept single character input from user, but when running the program, I get do..while loop executed multiple times. Please see the result of the program below.
If some one could help me with the answer, how to fix this problem?
import java.io.*;
public class Main {
/**
* #param args the command line arguments
*/
public static void main(String[] args) throws IOException {
char c;
// BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
DataInputStream in =new DataInputStream(System.in);
// Asking the user what to do with the application
do{
System.out.println("Would you like to access your account, if yes,type 'Y' or if you want to create a new account press 'N'to exit press 'E' ");
byte b = in.readByte();
c = (char) b;
c = Character.toUpperCase(c);
if (c=='Y'){
System.out.println(c);
}
else if (c=='N') {
System.out.println(c);
}
else if (c=='E'){
System.out.println(c);
}
else{
System.out.println("Incorrect Entry, try again: "+c);
}
}while (c!='E');
}
}
Output
init:
deps-jar:
compile:
run:
Would you like to access your account, if yes,type 'Y' or if you want to create a new account press 'N'to exit press 'E'
asdfgaf
Incorrect Entry, try again: A
Would you like to access your account, if yes,type 'Y' or if you want to create a new account press 'N'to exit press 'E'
Incorrect Entry, try again: S
Would you like to access your account, if yes,type 'Y' or if you want to create a new account press 'N'to exit press 'E'
Incorrect Entry, try again: D
Would you like to access your account, if yes,type 'Y' or if you want to create a new account press 'N'to exit press 'E'
Incorrect Entry, try again: F
Would you like to access your account, if yes,type 'Y' or if you want to create a new account press 'N'to exit press 'E'
Incorrect Entry, try again: G
Would you like to access your account, if yes,type 'Y' or if you want to create a new account press 'N'to exit press 'E'
Incorrect Entry, try again: A
Would you like to access your account, if yes,type 'Y' or if you want to create a new account press 'N'to exit press 'E'
Incorrect Entry, try again: F
Would you like to access your account, if yes,type 'Y' or if you want to create a new account press 'N'to exit press 'E'
Incorrect Entry, try again:
Would you like to access your account, if yes,type 'Y' or if you want to create a new account press 'N'to exit press 'E'

Using DataInputStream isn't probably the best way to handle your situation.
DataInputStream buffers the inputs that you typed, which is why you get unwanted lengthy messages with loops.
Try using Scanner instead.
Here's an example of Scanner:
Scanner objScanner = new Scanner(System.in);
char c = objScanner.next().charAt(0);
System.out.println(c);

Use System.in.read() instead of DataInputStream.

DataInputStream (InputStream) is fundamentally a binary construct. If you want to read text data (e.g. from the console) you should use a Reader. In the source code There was a commented out BufferedReader. Its better to use the same instead of DataInputStream. You can do as below,
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String input = in.readLine();
Or you can use DataInputStream.readLine(), but its deprecated for a reason. And its suggested there also to use BufferedReader.readLine().
You can go for other options like Scanner.

User Scanner class for getting input. Its good way to resolve your issue.
Scanner scan = new Scanner(System.in);
System.out.println(scan.next().charAt(0));

Since this thread has no ACCEPTED ANSWER yet, I'm still going to answer even though its really old; for the people who still want a explanation.
Using a Scanner are the best idea for the situation.
Scanners are easy to use, and stop the thread until completion. You can use this to your advantage, or you can create a new thread to keep the current thread running.
The basic usage of a scanner:
Scanner s = new Scanner(System.in) //Makes a new scanner with System.in
String letter = s.next(); //Use next to find the character typed
//Insert code using letter variable
"letter" will return EVERYTHING before a space in the scanner. To only find the first letter, split the string by "" then take the 1st (0th) of the array.
Lastly, a good quote taken from this thread about scanners
next() can read the input only till the space. It can't read two words separated by space. Also, next() places the cursor in the same line after reading the input.
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.
Later, when looking for multiple words, use nextLine() instead of next() to get the full String

Probably in above execution example you gave input as "asdfgaf" and then pressed enter.
hence it is taking A, S, D, F .... as input one character at a time.
you should give input as 'y' or 'n' or 'e' (single character at a time) and then press Enter.
e.g
Would you like to access your account, if yes,type 'Y' or if you want to create a new account press 'N'to exit press 'E' :
y

Related

Why my method being called 3 times after System.in.read() in loop

I have started to learn Java, wrote couple of very easy things, but there is a thing that I don't understand:
public static void main(String[] args) throws java.io.IOException
{
char ch;
do
{
System.out.println("Quess the letter");
ch = (char) System.in.read();
}
while (ch != 'q');
}
Why does the System.out.println prints "Quess the letter" three times after giving a wrong answer. Before giving any answer string is printed only once.
Thanks in advance
Because when you print char and press Enter you produce 3 symbols (on Windows): character, carriage return and line feed:
q\r\n
You can find more details here: http://en.wikipedia.org/wiki/Newline
For your task you may want to use higher level API, e.g. Scanner:
Scanner scanner = new Scanner(System.in);
do {
System.out.println("Guess the letter");
ch = scanner.nextLine().charAt(0);
} while (ch != 'q');
Using System.in directly is probably the wrong thing to do. You'll see that if your character is changed from q to something in Russian, Arabic or Chinese. Reading just one byte is never going to match it. You are just lucky that the bytes read from console in UTF-8 match the character codes for the plain English characters.
The way you are doing it, you are looking at the input as a stream of bytes. And then, as #Sergey Grinev said, you get three characters - the actual character you entered, and the carriage return and line feed that were produce by pressing Enter.
If you want to treat your input as characters, rather than bytes, you should create a BufferedReader or a Scanner backed by System.in. Then you can read a whole line, and it will dispose of the carriage return and linefeed characters for you.
To use a BufferedReader you do something like:
BufferedReader reader = new BufferedReader( InputStreamReader( System.in ) );
And then you can use:
String userInput = reader.readLine();
To use a Scanner, you do something like:
Scanner scanner = new Scanner( System.in );
And then you can use:
String userInput = scanner.nextLine();
In both cases, the result is a String, not a char, so you should be careful - don't compare it using == but using equals(). Or make sure its length is greater than 1 and take its first character using charAt(0).
As has been mentioned, the initial read command takes in 3 characters and holds them in the buffer.
The next time a read command comes around, it first checks the buffer before waiting for a keyboard input. Try entering more than one letter before hitting enter- your method should get called however many characters you entered + 2.
For an even simpler fix:
//add char 'ignore' variable to the char declaration
char ch ignore;
//add this do while loop after the "ch = (char) System.in.read();" line
do{
ignore = (char) System.in.read();
} while (ignore != '\n');
this way 'ignore' will cycle through the buffer until it hits the newline character in the buffer (the last one entered via pressing enter in Windows) leaving you with an fresh buffer when the method is called again.

How to skip control when we are using scanner readLine() when user is nothing entered from keyboard?

My code is :
System.out.print("press key Y or N to run the test");
Scanner sc = new Scanner(System.in);
String input = null;
input = sc.nextLine();
There is nothing you can do. nextLine() waits for the user to press "Enter" on the keyboard; it will block forever until that happens.
If you really want that things happen "automatically", you will need a more complex solution; for example you can wait for user input in a separate thread; and if there is no input after a given amount of time, your other thread can start doing "whatever" "automatically".
Please tell the user to hit return after his input and check for empty lines like this:
if("".equals(input)){ //skip control
}
else{ //do something on input
}

Java scanner - can't read user input

I want to read user input like: 11 12 13 14 15 16
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
System.out.println(sc.next());
}
System.out.println("Test");
but it newer goes out of while loop and prints "Test".
How could i read that input?
The method hasNext() works like this:
If it sees the end of the file, it returns false;
If it sees another valid, non-whitespace input, it returns true;
If neither of the above is true, it waits for the next input the user is going to enter, and doesn't return until he does.
Usually, if you use Scanner for files, such a loop will work correctly, because a file has a definite end, and it usually doesn't get stuck waiting for more input.
But when you are working with console input (System.in, not redirected), then usually the user does not send the end-of-file signal. He just presses Return, and so, hasNext() sits and waits to see if the user will enter more input on the next line and so on.
There are two general ways to deal with this:
The user has to actually terminate the input. After you finish entering all your numbers and press Return, you also need to send the end-of-file sequence, which is usually ctrlD or ctrlZ.
If you do that, you will not be able to enter any more input to that program.
The program tells the user to enter some particular value that will tell it that the input is over. For example, the string "DONE". When you do that, you have to change the loop to something like:
String nextInput;
while( sc.hasNext() && ! (nextInput = sc.next()).equals( "DONE" ) ){
System.out.println(nextInput);
}
You can break the loop depending whether you want to quit or not E.g.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String next = sc.next();
if (next.equals("q")) { //if user press q then break the loop
break;
}
System.out.println(next);
}
System.out.println("Test");
}
Use api like:
while(sc.hasNextInt()){
int aba= sc.nextInt();
if (aba == 0) {//or even non numeric value here would let this loop exit
break;
}
}
So you need to enter 0 or even in other way enter non numeric value inorder to come out of loop. nextLine method will read whole line just once and then you will need to parse it and then convert to integer so it's good to use sc.nextInt which will do the work for you.

I need to make Scanner check to see if input is "quit", and then if it's not, accept an integer

I'm trying to write a program that gets an integer from the user, but also ends the program if the user enters "quit". When I run the program, it works when I enter "quit", but when I start entering an integer, I get a blank line. If I enter the integer the second time, it works. I have tried several suggestions that I have found for similar problems - including try/catch, parsing the input to Integer, and firing a blank Scanner#nextLine or Scanner#nextInt (and going back and forth between all of these options). Here is an example of my latest attempt. Any insight would be appreciated.
int colInput;
System.out.println(", please pick a column in which to place your token (1-8).");
System.out.println("(Type 'quit' to exit the game or 'restart' to start over.)");
System.out.print("Column Choice: ");
Scanner selectCol = new Scanner (System.in);
try {
if (selectCol.next().equals("quit"))
Connect4.close();
}
finally {
colInput = selectCol.nextInt();
}
String input = selectCol.next();
int colInput;
if (input.equals("quit"))
Connect4.close();
else
colInput = Integer.parseInt(input);
//Use colInput here or return colInput or whatever you wish to do with it
In the code you mention you are consuming the "next token" found by your scanner in the line
if (selectCol.next().equals("quit"))
the token is received and compared against "quit". No matter what the value of the token originally was it is lost afterwards. Then later in the finally block you ask your scanner for a new token. He is then waiting for a new value from System.in.
To receive the token from the scanner only if it matches "quit" you should change the line to
if (selectCol.next("quit"))
This way you are making use of a method offered by the Scanner class javadoc for next(String).

java.util.Scanner: keeps waiting for additional input

Total Java newbie here. Working on one of my very first Java programs. Please help.
Here's what I am trying to achieve:
I need to accept user keyboard input of whitespace separated integers, copy them into an array and process them. KNOWN: user will enter only ONE line of data. I don't know how many numbers, but once they hit Enter, there won't be any more. As user input may contain words and special characters, I need to handle them with neat errors and prompt user to try again. When I run what I wrote below, I get in some kind of infinite loop where Scanner keeps waiting for additional input. How do I tell it it's over and there won't be any more input?
Here's the code:
<!-- language-all: java -->
public static void EnterInts () {
System.out.println("Enter series of integers separated by whitespace. Press Enter key when finished.");
Scanner input = new Scanner(System.in);
while (input.hasNext()){
if (input.hasNextInt(){
int i = input.nextInt();
System.out.println(i);
}
else {
System.out.println("Only integers can be entered. Try again.");
}
}
}
Seems like you should read the single line of input first, then create the Scanner to scan through that single line.
Try using a BufferedReader and InputStreamReader to read the line first:
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String str = in.readLine();
And then create the Scanner, perhaps passing a StringBufferInputStream created from the read string into its constructor.

Categories

Resources