Java method not waiting on BufferedReader input? - java

I have a BufferedReader waiting for input, but for some reason it doesn't wait for the second read and continues to print my third print statement.
Code:
BufferedReader inFromUser =new BufferedReader(new InputStreamReader(System.in));
char letter,xVal;
int yVal;
System.out.println("Please enter a letter for your word.(a-z)");
letter=(char)inFromUser.read();
System.out.println("Please enter a X location for this piece.(A-J)");
xVal=(char)inFromUser.read();
System.out.println("Please enter a Y location for this piece.(0-9)");
yVal=inFromUser.read();
Example execution goes as follows:
Please enter a letter for your word. //Waits on input here
a
Please enter a X location for this piece. //Doesn't wait here???
Please enter a Y location for this piece.

This is happening because once you press enter after typing a letter, you are also sending the newline character into the stream.
When you call read() the first time it returns the first character as expected. However, when you call read() the second time it will simply read in the newline character that is buffered in the stream, thereby seeming like it skipped over a read instruction.
The solution is to tell the BufferedReader to read the entire line, then fetch the first character from the line:
System.out.println("Please enter a letter for your word.(a-z)");
letter = inFromUser.readLine().charAt(0);
You may also want to improve upon this by doing some validation in case the user simply presses enter without inputting a letter.

The reason why it was not waiting is because xVal=(char)inFromUser.read(); was reading the "\n" from the line letter=(char)inFromUser.read();
So one solution it to add an inFromUser.readLine(); after each prompt:
System.out.println("Please enter a letter for your word.(a-z)");
letter=(char)inFromUser.read();
inFromUser.readLine();
System.out.println("Please enter a X location for this piece.(A-J)");
xVal=(char)inFromUser.read();
inFromUser.readLine();
System.out.println("Please enter a Y location for this piece.(0-9)");
yVal=inFromUser.read();
inFromUser.readLine();
You add a inFromUser.readLine(); after each prompt, so it can read the "\n".

Related

Multiple Iteration with System.in.read()

I am learning some basic IO right now and I decided to play around with some code, I wrote the following:
do{
System.out.print("Enter a char: ");
char x = (char)System.in.read();
if(x == 'q'){
break;
}
}while(true);
When I run this code and provide an incorrect input (ie anything that's not 'q') I get multiple prompts instead of 1.
Enter a char: s
Enter a char: Enter a char: Enter a char:
The same does not occur when using the Scanner object to read data.
Why is this occurring?
Thanks for any help.
char x = (char)System.in.read(); This line reads your inputs char by char. When you enter one char s and then press enter, actually you have two chars as follows;
s
\n (new line char, because you press enter)
Let's say you enter ab and then press enter, it means that you have 3 chars;
a
b
\n
So your code reads your input char by char on each iteration, and on each iteration you print Enter a char:.
But as you said that Scanner works just fine with same input. Because when you read input with Scanner.nextLine() you read your whole input as one string.
If you mark your code (inside loop) with breakpoint and debug it, you will see its behavior.

Using scanner in retrieving lines

am stuck with this question
6) Suppose you enter 34.3, the ENTER key, 57.8, the ENTER key, 789, the ENTER key. Analyze the following code.
Scanner scanner = new Scanner(System.in);
int value = scanner.nextDouble();
int doubleValue = scanner.nextInt();
String line = scanner.nextLine();
i know the answer, the line will be equal to '\n' when the last statement is executed but why?
can anyone please explain it for me please?
The Scanner reads as many tokens as necessary to get it's next output and then leaves all of the rest of the tokens there to be examined. nextInt() does not need the newline character so it leaves it in the token stream. When you call nextLine() it looks into the token stream, sees the newline character, and returns that.
Let's break this statement by statement.
Scanner scanner = new Scanner(System.in);
int value = scanner.nextDouble();
The system waits for you to type in the value.
34.3↲
The value is read as 34.3 but is truncated to 34 since it is stored as an integer. Now the next statement is executed.
int doubleValue = scanner.nextInt();
The system waits for you again to type in the value.
57.8↲
The value is read as 57 as you are using scanner.nextInt() and hence, the .8 is ignored. There is however a enter remaining in the buffer.
String line = scanner.nextLine();
The system now waits again for the input, and you type in this. The first new line is the remnant from the previous input.
↲
789↲
The scanner first sees the newline character, so it assumes that the line is terminated. So the value is read as \n
Hope this helps.

Java - if/else fails immediately when supposed to pause

I'm having troubles with a function in java. Here's my code:
do{
System.out.print("Proceed to payment? (y/n) ");
input = scan.nextLine();
if((input.trim()).equals("y")){
break;
}
else if((input.trim()).equals("n")){
System.out.print("Come back next time, " + name + ".");
System.exit(0);
}
else{
System.out.println("Invalid response. Try again.");
}
}
while(true);
Basically, the first time the function loops it 'skips' the "input = scan.nextLine" and immediately prints "Invalid response. Try again." to the terminal. It then allows the user to input something, and works normally.
Yes, I have declared input, scan (java.util.Scanner;), and name earlier in my code. It'd be a great help if someone can point out what I've done wrong! Thanks!
While adding scan.nextLine() before does help, I keep a general rule of setting the delimiter whenever I initialize the Scanner class by using:
scan.useDelimiter("\n");
in this case, which uses a newline as a delimiter. As a result, for all the methods of scan, whenever the user presses Enter, it is interpreted as the end of the input. This includes, nextInt(), nextDouble(), next()etc...
Using the delimiter also means that I don't have to add scan.nextLine() after every non-nextLine() input.
You probably called scan.next(), or something like that, before entering the do-while loop. That left a next line character in the input, and the call to scan.nextLine() consumed it. To fix it, you could place a scan.nextLine() call right after scan.next() so it will consume the next line before entering the loop.
For example:
Scanner scan = new Scanner(System.in);
String input;
String name = scan.next();
scan.nextLine();
do {
System.out.print("Proceed to payment? (y/n) ");
input = scan.nextLine();
// rest of the code
}
while(true);

How to take single character input from user in 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

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