Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I'm trying to read multiple line input like a copy past input, but I can't end the while loop to stop reading. Here is my code:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String input =null;
while(sc.hasNext()) {
input=sc.next();
}
String [] split = input.split(" ");
for(int i = 0;i<split.length;i++) {
for(int j = split[i].length()-1;j>=0;j--) {
System.out.print(split[i].charAt(j));
}
System.out.print(" ");
}
sc.close();
}
}
Use buffer reader class, by this you'll be able to take multiple inputs at the same time.
https://docs.oracle.com/javase/6/docs/api/java/io/BufferedReader.html
The hasNext() method will look if there is something to read. To do so it might block and wait on the used InputStream as described in the documentation of hasNext():
public boolean hasNext()
Returns true if this scanner has another token in its input. This method may block while waiting for input to scan. The scanner does not advance past any input.
When the InputStream ends it will return from the hasNext() call and return false, since there is no token to read (and the source of data/bytes is closed). But since you are reading from the keyboard via System.in there is no "end" of input because you still can enter new text into your application, which your while() loop will read.
There are several solutions for this:
Depending on how you start your java application, you can press CTRL-D to explicit close the so called "STDIN" stream which is "attached" to your keyboard input. That way the stream System.in will end and no further data can be read. This is also detected by the Scanners hasNext() method, which will return false at that point.
You can call your java application where you provide the data for the "STDIN" stream via a file or via other commands. Examples of these are: echo "data" | java Main or java Main < inputData.txt (depending on the terminal/console you are using).
Add an end marker to your content and look for it. When you place a text like "MY_TEXT_END" in your data and look for it you can use a simple equals() check inside the while() loop and stop reading when you have seen your marker "MY_TEXT_END".
Since you are using while loop and it will loop/execute through a block of code as long as a specified condition is true/met.
And here you are checking any condition to exit the loop.This method may block while waiting for input to scan and the scanner does not advance past any input.
Another gap that I see is, you are re-assigning the input to input var again and again without performing any operation beforehand accepting next line.
You can get more clarity on exiting the while loop here :
How to get out of while loop in java with Scanner method "hasNext" as condition?
Scanner sc = new Scanner(System.in);
String input = null;
while(sc.hasNext() && !(input = sc.next()).equals("exit")) {
System.out.println(input);
}
sc.close();
So, to answer your question, you must provide some check/exit condition for while loop to in-validate and exit out of the loop.
Related
This question already has answers here:
How to get out of while loop in java with Scanner method "hasNext" as condition?
(9 answers)
Closed 1 year ago.
I have this code:
public class SimpleTest {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter: ");
String s = "";
while (scanner.hasNext()) {
s += scanner.next();
System.out.println(s);
}
System.out.println("Result: " + s);
}
}
My code shows:
While Result: line never gets printed.
How do I fix it? (Without using scanner.nextLine, .split() or a different while condition like whle (!input.equals("quit"))
When scanning a file eventually the scanner gets to the end of stream marker and so it knows there's no more data to scan and so hasNext() returns false. However, when scanning from the command line there is no end of stream marker so hasNext() bocks waiting for the next chunk of data (or the end of stream marker).
You need to decide how you are going to end command line input, eg is it on entering a specific number of item or putting your input followed a specific keystroke/keyword eg END, EOF, STOP etc. You then need to add code to your while loop to find the end of input marker and exit the loop.
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 5 years ago.
public static char[] puzzleInput() {
printEnterPuzzleMessage();
Scanner puzzleS = new Scanner(System.in);
if(puzzleS.hasNext()) {
char[] puzzle = puzzleS.next().toCharArray();
while(!isLegalPuzzleStructure(puzzle)) {
printIllegalPuzzleMessage();
puzzleInput();
}
return puzzle;
}
puzzleS.close();
return null;
}
public static void main(String[] args) throws Exception{ //Q - 8
Scanner fileName = new Scanner(System.in);
if(!fileName.hasNext()) {
System.out.println("No argument has been received");
System.exit(0);
}
String filePath = fileName.nextLine();
fileName.close();
Scanner vocabulary = new Scanner(new File(filePath));
String[] vocabularyArr = scanVocabulary(vocabulary);
vocabulary.close();
printReadVocabulary(filePath, vocabularyArr.length);
printSettingsMessage();
printEnterPuzzleMessage();
char[] puzzle = puzzleInput();
Hi, a beginner in Java is here.
In the function puzzleInput, I open a Scanner to get an input from the user. For some reason, the program won't give me a chance to put in input, and therefor the argument (puzzle) gets a null as default, and later when puzzle is needed not as a null - throws a NullPointerException.
There are many other functions in the code, but most of them are just a print commands, and the ones who are not were being checked by me, and are OK.
The problem is just the scanner won't give me a chance to put in an input.
Some points I'd like to clarify further:
1. The first Scanner (fileName) is not being skipped by the program, and I'm able to give it an argument.
2. I made sure I closed all the other scanners i've opened before.
Can someone explain me what I'm doing wrong?
program won't give me a chance to put in input
Your problem is that you are closing your Scanner in main:
Scanner fileName = new Scanner(System.in);
...
fileName.close();
This in turn closes the System.in input-stream which then cannot be reused in your puzzleInput() method because it is already closed. The right thing to do here is to pass in the Scanner variable into your puzzleInput() method and continue to reuse it there and not try to open up a new Scanner.
public static char[] puzzleInput(Scanner scanner) {
printEnterPuzzleMessage();
if(scanner.hasNext()) {
...
// don't close it here
return null;
}
...
Scanner scanner = new Scanner(System.in);
...
puzzleInput(scanner);
Couple of other comments:
Calling a Scanner fileName is not a good pattern. Choosing good names for your variables will help make the code self-documenting. scanner would be a better name of course.
When dealing with any input/output, it is a good practice to wrap any opening method in a try/finally block so it gets close properly. See also the try-with-resources functionality added in Java 7.
If you want a chance to do something with the input with a prompt, why not assign it to a String variable? This allows you to manipulate the input however you want later on too.
String input = scannerName.nextLine();
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 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();
}
}
I'm trying to read commands via a Scanner Object. For checking the Input Syntax I use sc.hasNext() (for the case of missing commands). It did work fine for many cases already, but now I have the case that's described in the JavaAPI as "MAY block and wait for Input".
When does the hasNext() method block and how can I control it? The funny Thing is that it work's perfectly fine with 3 cases before the block. Also the JavaAPI describes hasNext() as the proper method for checking wether there is another Input or not so that the Method next() doesn't produce an Exception.
Here is the code I did produce till now:
if (sc.hasNext() && sc.next().equals("create")) {
if (sc.hasNextInt()) {
width = sc.nextInt();
if (width > 0) {
if (sc.hasNextInt()) {
heigth = sc.nextInt();
if (heigth > 0) {
if (sc.hasNext()) { //At this point the hasNext Statement blocks for //no reason till an Input is made.
charset = sc.next();
Image = new AsciiImage(width, heigth,charset);
} else {
ret = false;
System.out.println("INPUT MISMATCH");
}
} ...//and so on
Thanks in advance, I couldn't find anything on this Topic an my own.
Edit: The Scanner is defined as a System.in, but that shouldn't be a Problem - at least it hasn't been one till now.
There is a difference between testing via Console or via TextFile. If I read from Console the program expects a Stream and it will wait for further Input.
When testing via Input from Textfile (still with System.in for the Scanner, using Java Program ) the hasNext() will return false at the end of the file as no further Input can be done.
I can't really find documentation (in https://docs.oracle.com/javase/9/docs/api/java/util/Scanner.html#hasNext--) on this Topic. So if anyone finds a proper and technical correct answer I would be very greatfull.
If you have nothing else to do while waiting for user input, then it's fine to be blocked at that call until the next input arrives.
If you do want to run other code while waiting for input, spawn a new thread and call hasNext and other blocking scanner methods from there.
I'm not sure , but the following is my own experience :
when the Scanner object is fed with a file , it will not be blocking !
By the term "fed with a file " I mean that the scanner is constructed like this : Scanner scanner = new Scanner("myFile.txt");
But if the scanner is constructed using the getInputStream()method of a Socket object , like this :
input = socket.getInputStream();
Scanner scanner = new Scanner(input);
the scanner will be blocking !