Java Scanner or Buffered Reader - java

I have a requirement where I will have to read inputs from console not from file
The input format is as below.I understand I can use any character to exit .But i cannot give any other input than this.Can i write some thing like wait for a specific amount of time and if there is no input break the loop or else what else can be done to read input whose length we never know before hand.
Hello,Agnes
Minion,Bedo
Vector,Shrink Ray
This following logic will make the readline wait forever for the input and wouldn't help because every enter I press will again be another input character and it never ends.
I neither wanna give any exit character to determine end of input like "exit". How to handle this??
ArrayList<String> emp=new ArrayList<String>();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
h=br.readLine();
while((h=br.readLine()) != null)
{
emp.add(h);
}

You could add a thread that requests the users input, and then a Timer that's started over on each new input. When the timer expires, it shuts the user input thread down.

Scanner reader = new Scanner(System.in);
System.out.println("Enter something: ");
String s=reader.nextLine();
System.out.println("You enetered: " + s);
Which results in:
Enter something:
Mike,Elofson
You enetered: Mike,Elofson
Generally speaking, and from my experience, scanners are easier and more commonly used for input.

How about a "" input(namely press Enter directly), or two/three consecutive "" inputs.
I don't think waiting for some time is a good idea. Anyway, you need some input to indicate the end.

Related

How can I clear the input buffer to ignore input given before prompt?

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.

Scanner.next() and hasNext() creating infinite loop when reading from console [duplicate]

I ran into an issue. Below is my code, which asks user for input and prints out what the user inputs one word at a time.
The problem is that the program never ends, and from my limited understanding, it seem to get stuck inside the while loop. Could anyone help me a little?
import java.util.Scanner;
public class Test{
public static void main(String args[]){
System.out.print("Enter your sentence: ");
Scanner sc = new Scanner (System.in);
while (sc.hasNext() == true ) {
String s1 = sc.next();
System.out.println(s1);
}
System.out.println("The loop has been ended"); // This somehow never get printed.
}
}
You keep on getting new a new string and continue the loop if it's not empty. Simply insert a control in the loop for an exit string.
while(!s1.equals("exit") && sc.hasNext()) {
// operate
}
If you want to declare the string inside the loop and not to do the operations in the loop body if the string is "exit":
while(sc.hasNext()) {
String s1 = sc.next();
if(s1.equals("exit")) {
break;
}
//operate
}
The Scanner will continue to read until it finds an "end of file" condition.
As you're reading from stdin, that'll either be when you send an EOF character (usually ^d on Unix), or at the end of the file if you use < style redirection.
When you use scanner, as mentioned by Alnitak, you only get 'false' for hasNext() when you have a EOF character, basically... You cannot easily send and EOF character using the keyboard, therefore in situations like this, it's common to have a special character or word which you can send to stop execution, for example:
String s1 = sc.next();
if (s1.equals("exit")) {
break;
}
Break will get you out of the loop.
Your condition is right (though you should drop the == true). What is happening is that the scanner will keep going until it reaches the end of the input. Try Ctrl+D, or pipe the input from a file (java myclass < input.txt).
it doesn't work because you have not programmed a fail-safe into the code. java sees that the scanner can still collect input while there is input to be collected and if possible, while that is true, it keeps doing so. having a scanner test to see if a certain word, like EXIT for example, is fine, but you could also have it loop a certain number of times, like ten or so. but the most efficient approach is to ask the user of your program how many strings they wish to enter, and while the number of strings they enter is less than the number they put in, the program shall execute. an added option could be if they type EXIT, when they see they need less spaces than they put in and don't want to fill the next cells up with nothing but whitespace. and you could have the program ask if they want to enter more input, in case they realize they need to enter more data into the computer.
the program would be quite simplistic to make, as well because there are a plethera of ways you could do it. feel free to ask me for these ways, i'm running out of room though. XD
If you don't want to use an EOF character for this, you can use StringTokenizer :
import java.util.*;
public class Test{
public static void main(){
Scanner sc = new Scanner (System.in);
System.out.print("Enter your sentence: ");
String s=sc.nextLine();
StringTokenizer st=new StringTokenizer(s," ");//" " is the delimiter here.
while (st.hasMoreTokens() ) {
String s1 = st.nextToken();
System.out.println(s1);
}
System.out.println("The loop has been ended");
}
}
I had the same problem and I solved it by reading the full line from the console with one scanner object, and then parsing the resulting string using a second scanner object.
Scanner console = new Scanner(System.in);
System.out.println("Enter input here:");
String inputLine = console.nextLine();
Scanner input = new Scanner(inputLine);
List<String> arg = new ArrayList<>();
while (input.hasNext()) {
arg.add(input.next().toLowerCase());
}
You can simply use one of the system dependent end-of-file indicators ( d for Unix/Linux/Ubuntu, z for windows) to make the while statement false. This should get you out of the loop nicely. :)
Modify the while loop as below. Declare s1 as String s1; one time outside the loop. To end the loop, simply use ctrl+z.
while (sc.hasNext())
{
s1 = sc.next();
System.out.println(s1);
System.out.print("Enter your sentence: ");
}

Read large input through Scanner

I am trying to take some user input and process them in my program. For that using the Scanner class as below.
Scanner scan = new Scanner(System.in);
System.out.print("Input : ");
String input = scan.nextLine();
// Process the Data
scan.close();
The program works fine with small amount of data. But if the input string length is huge (~100K characters), Scanner stops responding and fails to read any data.
Is there any different way or workaround to this problem ?
Note : These is no possible way to store the data in a file and read from there. It would be a nice option to read chunks of data from a file. But unfortunately there is no such implementation in my application.
EDIT : As mentioned earlier, I need to read data directly from user (not from a file). Anyway, already tried to use the BufferReader. But does not seem like can read some data of around 100K characters.
Here is the code below.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Input : ");
String input = br.readLine();
// Remaining Code
Well this behavior might be normal, you'll have to wait for a moment before the Scanner code does anything. It's a big input and I guess the OS has to put it somewhere, so there is certain amount of time between the moment you press enter and the moment the JVM can read it.
You should benchmark it to see how much reading time evolves depending on you input.
I've made a code that read character per character from input. It is not a good solution as it surely is slower (and dirtier) than using nextLine(), but it will show how fast is the buffering and reading on your computer:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
Log.d("Input : ");
StringBuilder test = new StringBuilder();
String input = "";
long measure = 0;
while(input != null){
input = scan.findInLine("."); // Should consume input one char per one char.
measure++;
if(input != null)
test.append(input.charAt(0));
if(measure == 1 || measure % 1000 == 0) // displays the reading time of first reads and the next thousand ones
Log.d("Reading at:"+measure);
}
Log.d("End");
scan.close();
Log.d("size: "+test.toString().length());
}
}
(note: you can replace Log.d(yourString) by System.out.println( new Date() +":" +yourString ) )
Test with this on your computer and gradually increase the input. I'm not sure the response is linear. It works well with 50000 char but it's in fact quite long with 100.000 (still, only a few minutes before I can read the first character).
edit: the time between reads also increases with input size ... it takes 80 seconds for 1000 char reads with an 100.000 chars input (and a few seconds with 50.000). At this rate, it will take more than 2 hours to read everything.
I'm not sure, looping on System.in.read(); might have better results (I don't know what the line end character is however ... \EOF maybe ?), but you can still try that too. Again, I don't think it's a good solution, but reading from the comment, it's all you got left.

Reading lines of input from user using SCANNER

I have a program that needs to read lines of input. It needs to be many lines at once. For example:
As I enter my time machine or
maybe not,
I wonder whether free will exists?
I wonder whether free will exists
maybe not
as I enter my time machine or.
That all gets entered at one time by the user. I was trying to use .hasNextLine() method from Scanner class, but it is not returning false.... it waits for input again. Ive been looking around for a solution and it appears that .hasNextLine() waits for input, but i do not know what alternative to use. Any suggestions? The actual code looks like:
while(input.hasNextLine());
{
line += input.nextLine();
}
Thanks for your help
Perhaps you should use some sort of "stop" sequence meaning when the user enters a particular character sequence, it will break out the loop. It might look something like:
public static void main(String args[]){
final String stopSequence = "/stop";
final Scanner reader = new Scanner(System.in);
String input = reader.nextLine();
while(!input.equalsIgnoreCase(stopSequence)){
//process input
input = reader.nextLine();
}
}

Trying to write a method that checks user input in JAVA, getting NoSuchElementException [duplicate]

This question already has an answer here:
How to use java.util.Scanner to correctly read user input from System.in and act on it?
(1 answer)
Closed 7 years ago.
I am trying to write a method to handle all my input from the user in a console application. I call this method a total of 5 times. The first time, the condition is
a) the number must be positive and real-valued (double)
the next 4 times the condition is
b) the number must be greater than 1
This is my method:
private static double numChk(int errNum) {
final String[] ERROR_MESSAGE = {
"\nPlease enter only positive, real-valued numbers",
"\nPlease enter only positive numbers greater than 1" };
Scanner in = new Scanner(System.in);
double tempData;
while (!in.hasNextDouble()) {
System.out.println(ERROR_MESSAGE[errNum]);
System.out.print(" Please try again: ");
in.next();
}
tempData = in.nextDouble();
// in.close();
return tempData;
}
this is an example call to this method:
do {
System.out
.println("Please enter only positive, real-valued numbers");
System.out.print(" Enter a constant: ");
mu = numChk(0);
} while (mu <= 0);
note the "// in.close();" in the method I wrote. Without closing the Scanner in, this method works fine. However, my assignment requires me to make sure I close all open input streams. if I close the input stream in the method and re-open it, I get a NoSuchElementException. I know I could just put all of this into my main method and close the input at the end of it however, I would like to know if there is a way to do this (input validation, multiple times) and be able to close the input stream.
When you call in.close() you are also closing the System.in. The next time you try to use a new Scanner, it will try to use a closed System.in, and that is why you get an exception when you try to read from it
See:
Using Scanner.next() to get text input
If you call in.close() in the method, you need some way of determining if it is the last input or not.
I would recommend putting the scanner in your main method, passing the scanner in to the method, and then closing it when you're done with all your input.
What I suspect is happening is you're sending the input piped as if from a file. The first scanner buffers all the input, and when you close and re-open it, you end up losing the data that was buffered to the first scanner. I can't guarantee that, but that's what it looks like.
After while loop it tries to call, by this line there may not be any inputs.
tempData = in.nextDouble();

Categories