Standard input gets stacked - java

i have problem with my program, specificly with Standart input.
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
int in;
while ((in = input.read()) != -1) {
System.out.println(((char) in));
System.out.println("going throught while loop");
}
System.out.println("while loop ended");
input.close();
I would have expected that after input has been printed, the line "while loop ended" would be printed as well, but here is what i get when i wrote "hi" into eclipse console as input
...............................
hi
h
going throught while loop
i
going throught while loop
going throught while loop
going throught while loop
.........................
and the program still runing, and waiting for another input, so the rest of the code under while loop is not executed, so I am asking you how to make it just one time input, that I input some word or so and then the code will leave while loop, in other words, the line "while loop ended" will be printed.
Thank you all for any advise.

Since you are using a BufferedReader, you may just call its readLine method to obtain the line the user has typed. If you only need one line, you don’t need a loop.
Another option is looking into java.util.Scanner.
Whether you go with one or the other, there are plenty of tutorials and code examples out there for you to use.

According to ASCII, your buffer is reading 104(h) 105(i) and 10(LF) and 13(CR). That is, you are reading 'hi' plus the line terminator and next line. You could change your while to the following structure:
while ((in = input.read()) != -1 && in != 13 && in != 10)
I have seen it when I changed the your sysout to print the int value.
If you can read all the line and print each char in the String, do as follow:
Scanner input = new Scanner(System.in);
String text = input.nextLine();
for(char ch: text.toCharArray()){
System.out.println(ch);
System.out.printf("going throught while loop \n");
}
System.out.println("while loop ended");
input.close();

Related

Input multiple lines using hasNextLine() is not working in the way that I expected it to

I'm trying to input multiple lines in java by using hasNextline() in the while loop.
Scanner sc = new Scanner(System.in);
ArrayList<String> lines = new ArrayList<>();
while (sc.hasNextLine()) {
lines.add(sc.nextLine());
System.out.println(lines)
}
The code is inside the main method. But the print method in thewhile loop doesn't print the last line of my input. Also, while loop doesn't seem to break.
What should I do to print whole lines of input and finally break the while loop and end the program?
Since an answer that explains why hasNextLine() might be giving "unexpected" result has been linked / given in a comment, instead of repeating the answer, I'm giving you two examples that might give you "expected" result. Whether any of them suits your needs really depends on what kind of input you need the program to deal with.
Assuming you want the loop to be broken by an empty line:
while (true) {
String curLine = sc.nextLine();
if (curLine.isEmpty())
break;
lines.add(curLine);
System.out.println(curLine);
}
Assuming you want the loop to be broken by two consecutive empty lines:
while (true) {
String curLine = sc.nextLine();
int curSize = lines.size();
String LastLine = curSize > 0 ? lines.get(curSize-1) : "";
if (curLine.isEmpty() && LastLine.isEmpty())
break;
lines.add(curLine);
System.out.println(curLine);
}
// lines.removeIf(e -> e.isEmpty());

Is there a way around not advancing a line with Scanner (Java)

Okay so I'm having a slight problem with scanner advancing an extra line. I have a file that has many lines containing integers each separated by one space. Somewhere in the file there is a line with no integers and just the word "done".
When done is found we exit the loop and print out the largest prime integer that is less than each given integer in each line(if integer is already prime do nothing to it). We do this all the way up until the line with "done".
My problem: lets say the file contains 6 lines and on the 6th line is the word done. My output would skip lines 1, 3 and 5. It would only return the correct values for line 2 and 4.
Here's a snippet of code where I read the values in:
Scanner in = new Scanner(
new InputStreamReader(socket.getInputStream()));
PrintStream out = new PrintStream(socket.getOutputStream());
while(in.nextLine() != "done"){
String[] arr = in.nextLine().split(" ");
Now I sense the problem is that the nextLine call in my loop advances the line and then the nextline.split call also advances the line. Thus, all odd number lines will be lost. Would there be another way to check for "done" without advancing a line or is there a possible command I could call to somehow reset the scanner back to the start of the loop?
The problem is you have 2 calls to nextLine() try something like this
String line = in.nextLine();
while (!"done".equals(line)) {
String[] arr = line.split(" ");
// Process the line
if (!in.hasNextLine()) {
// Error reached end of file without finding done
}
line = in.nextLine();
}
Also note I fixed the check for "done" you should be using equals().
I think you are looking for this
while(in.hasNextLine()){
String str = in.nextLine();
if(str.trim().equals("done"){
break;
}else{
String[] arr = str.split("\\s+");
//then do whatever you want to do
}
}

reading multiple lines of input always runs an infinite loop unless I print each line

I'm trying to process multiple lines of input from the console using a Scanner in Java, and it runs in an infinite loop unless I print out each line. For some reason the next line is not 'consumed' unless I print it. I don't want to print it, I only want to add each line to an array to process later, so I don't know how to 'consume' each line w/o printing it. Both of these loops are infinite:
while(sc.hasNext()) {
String line = sc.nextLine();
commands.add(line);
//System.out.println(line);
sc.nextLine();
}
while(sc.hasNext()) {
String line = sc.nextLine();
commands.add(line);
//System.out.println(line);
//sc.nextLine();
}
EDIT:
My scanner initialization is below, and I also edited the condition to hasNextLine(), still running an infinite loop. That print statement that prints "done" never excecutes.
Scanner sc = new Scanner(System.in);
ArrayList<String> commands = new ArrayList<String>();
while(sc.hasNextLine()) {
String line = sc.nextLine();
commands.add(line);
//System.out.println(line);
//sc.nextLine();
}
System.out.println("done");
You should be calling hasNextLine(), not hasNext().
Printing has nothing to do with it. Printing doesn't terminate loops.
EDIT If you are never seeing your final "done", this isn't an infinite loop at all, it is a block: you're never sending an end of stream to System.in. Type Ctrl/d or Ctrl/z depending on Windows vs. Unix/Linux/... and again, printing has nothing to do with it.

Code Behaving Differently On Different IDE

I am writing a program that takes information about a track and field competition and then does some computation with it. The issue I'm having now is only in the first user input section.
I first wrote my code in BlueJ and it worked fine. Then, I tried compiling it in JCreator and started getting this error where the program would only receive 3 user inputs before going onto the next piece of code when it should have received 5 (which it did when I compiled in BlueJ).
When I placed a System.out.println statement after the input statement however, the program (in JCreator) DID receive all 5 statements before proceeding. When I commented it out again, it only received 3 statements before continuing. Here is the code below.
String[] events = new String[5];
System.out.println("Please enter the 5 events in this competition.");
for(int i = 0; i < events.length; i++)
{
events[i] = input.nextLine();
System.out.println(i);
}
This is the output with the System.out.println statement.
This is the output with the System.out.println statement commented out.
Change the line
events[i] = input.nextLine();
to
String newLine;
while( (newLine = input.nextLine()).isEmpty() );
events[i] = newLine;
That should consume the extra newline characters and leave you with just the legitimate input in events.
The possible cause of your problem is newline characters, which are interpreted as line. It seems you are having additional newline characters in your input buffer.
You may check your IDE what character is provided when an enter key is pressed.
It seems you are using Scanner class to read input. You may try to wrap your System.in with InputStreamReader, that might help. (not sure, try it out)
Scanner input = new Scanner(new InputStreamReader(System.in));
events[i]=input.nextLine();
Instead you may also try to use BufferedReader to read the input.
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
events[i]=reader.readLine();
Hope it will help!!

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.

Categories

Resources