This question already has answers here:
System.in.read() does not block to read more input characters? [duplicate]
(3 answers)
Closed 8 years ago.
I have a project the is suppose add an input to an array list. I used scanner.util for my input, I'm suppose to input a Title = (String) and ID = (int), after input the project then provides me an option to input another or exit, for this i used while loop that when the input value is not equal to "Exit", loop. The problem is my project skips the input option to Exit or continue, does anyone have any idea how to fix it???
here is the code
String option = "";
while(!option.equals("Exit"))
{
System.out.println("Add your New Movie below\n");
movie.setName(input.nextLine());
movie.setid(input.nextInt());
System.out.println("Type in 'Quit'to end, type anything to add another Movie");
movieList.add(movie.getid() + " " + movie.getName());
option = input.nextLine();
}
Well, the problem is pretty obvious, the methods nextXXX in java.util.Scanner will only read the value of type XXX.
This means your return character "\n" is still available for read, so the input Exit is not even tested the option is always tested against a "\n".
I suggested using a better InputStream reader, or BufferedReader or anything else. If you still want go with this code then add another option.nextInt(); at the end of this loop.
String option = "";
while(!option.equals("Exit"))
{
System.out.println("Add your New Movie below\n");
movie.setName(input.nextLine());
movie.setid(input.nextInt());
System.out.println("Type in 'Quit'to end, type anything to add another Movie");
movieList.add(movie.getid() + " " + movie.getName());
option = input.nextLine();
option = input.nextLine();
}
nextInt() only reads the next int from the input stream, and leaves any other characters on the stream.
When you press "enter" after entering an ID, your computer sticks either a newline character ('\n') on *nix systems or a newline and a carriage return ("\r\n") on Windows systems at the end of the line. So this is what happens on a *nix system when you enter the ID:
User input:
> 5\n
Process next int: return 5
// So now "\n" is left on the input stream
// Code goes to option = input.nextLine()
// "\n" is still on the input stream, so nextLine() immediately returns an empty string
You should read the entire line when getting the next integer and use Integer.parseInt() to extract its value.
Related
This question already has answers here:
How to keep my user input on the same line after an output?
(4 answers)
Closed 3 years ago.
I want to print a line like this:
Result: [the result are input here and after click on Enter to continue]
How can I do that?
EDIT:
This is what I want:
Scanner user1 = new Scanner(System.in);
int x = user1.nextInt();
System.out.println("Result: "+x);
But the last line won't print unless I type my input and press Enter.
Using java, you simply could use System.out.print(); to display it in console and after adding the capture info:
System.out.print("Result: ");
int x = user1.nextInt();
This is a very old thread but since there doesn't seem to be an accepted answer, I am answering. Hope it would help someone else...
Here is what you are looking for
Scanner input = new Scanner (System.in);
System.out.print("Enter a number : ");
int num = input.nextInt();
System.out.println("Hello you entered "+num);
Note that when you use println the cursor moves to next line.
If you use just print the next statement continues on the same line.
Hope this one will work. Please try
Input str =scanner. readLine("Result:" ) ;
Int inp =integer.parseInt(star) ;
The last line will not print unless you type an input and press enter as the code is run line by line. First you have to enter the value. Since it runs on console for the next step to be pressed you have to press enter.
So whatever you said will naturally happen and cannot be avoided.
Based on the code snippet you sent there is nothing wrong with the code and the logic in it and these are basic java steps.
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 7 years ago.
While I'm working with java.util.Scanner, I tried to use integers and Strings at data input.
The problem that I faced is, when I input an Int data before a String one, the console skip the String data and go immediately to the next Int one.
Here is my simple problem where the problem is happening :
package justForTest;
import java.util.Scanner;
public class EmptySpaceWorkshop {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("- Enter your Name : ");
String name = input.nextLine();
System.out.print("- Enter your IC number : ");
int icNumber = input.nextInt();
System.out.print("- Enter your Place of birth : ");
String placeOfBirth = input.nextLine();
System.out.print("- Enter your Age : ");
int age = input.nextInt();
System.out.println("There once was a wonderful person named " + name+ ", His IC number is " + icNumber );
System.out.println(". He/She is " + age + " years old. She/He was born at " + placeOfBirth );
}
}
And here is my output:
- Enter your Name : Ali HISOKA
- Enter your IC number : 123456
- Enter your Place of birth : - Enter your Age :
I tried a lot to fix this problem. The only solution I could came up with is using input.next(); instead of input.nextLine(); . However, this solution is USELESS for me because as you guys know, when using input.next(); we can only type One Single Word, unlike input.nextLine(); we can type a lot of words which is the thing that I'm looking for. Also I DO NOT want to re-sort (re-arrange) my input and type the Strings data first, then following by the Int data to solve my problem. I want my data to be at the same sort as you seen above in my simple program ( Enter Name, Enter IC Number, Enter Place of Birth, then Enter age). So can I solve this problem ?
I searched a lot on the internet for someone got a problem as mine, but I couldn't find a question and solution for a problem looks exactly like mine.
I already know the reason and the explanation of my problem which is explained by
Joshua
"The reason for the error is that the nextInt only pulls the integer,
not the newline. If you add a in.nextLine() before your for loop, it
will eat the empty new line and allow you to enter 3 names."
but still it's not helpful for solving my problem.
Think of your input as a single string:
"Ali HISOKA\n123456\nPLACE\n99"
next() consumes the first word, up to first white space - e.g. " " or "\n"
nextLine() consumes the first word, up to first new line character
nextInt() consumes first word, as next(), and parses it to int - it will throw an exception if the word cannot be parsed.
Now, let's have a look what your calls are consuming:
nextLine() will return "Ali HISOKA", the remaining string is "123456\nPLACE\n99"
nextInt() will return int 123456, the remaining string is "\nPLACE\n99"
nextLine() will return empty string "", the remaining string is "PLACE\n99"
nextInt() will throw an exception, because it will try to parse "PLACE" to int.
The trick is in step 2 - although nextInt() consumes all white spaces between words, it however does not consume new line character, hence nextLine() in step 3 reads empty string because "\n" is first character in the remaining string.
There are two solutions:
Instead of using nextInt() you can read and parse the whole line Integer.parseInt(input.nextLine()). If the line contains a few words, e.g. "1234 abc" it will throw the exception.
Call input.nextLine() after calling nextInt(), so it consumes the remaining string up to first new line character. For input "1234 abc" it will ignore everything after the number.
I would recommend the first solution, because when you are asked for the number and you answer "123 abc", it is not a valid answer. In such case the user should be told that the input is invalid, instead of taking only a valid part from that answer - user would have no clue that part of his answer was ignored.
From what I can see it appears that the readLine() is just consuming the newline left after the int was taken from the buffer. A better way to fix this is to use nextLine() to get a string value and convert it:
int icNumber = Integer.parseInt(input.nextLine());
This is a bit confusing because the code you posted does not show your original problem, but the situation after putting in a workaround.
You need to skip the newline after nextInt()
System.out.print("- Enter your IC number : ");
int icNumber = input.nextInt();
input.skip("\\n");
Without the skip, input.newLine (for the place of birth) will match the newline after the entered IC number and you will be prompted for the age.
I tried your code at my machine without making any changes and Its working fine.Below is my output.
Enter your Name : yash
Enter your IC number : 12
Enter your Place of birth : alg
Enter your Age : 25
There once was a wonderful person named yash, His IC number is 12
. He/She is 25 years old. She/He was born at alg
I'm having trouble understanding the source below:
myChar1 = myScanner.findWithinHorizon(".",0).charAt(0);
System.out.println(myChar1);
myChar2 = myScanner.findWithinHorizon(".",0).charAt(0);
System.out.print(myChar2);
I understand what it does, but I'm just having a bit of a trouble understanding how it works.
The actual prompting of the user for input is done at the first line right? but the real meaning of the first line is: "put the first char of input in myChar1". Then what happens? It seems the input still stays inside myScanner because when I use it in myChar2 I get the second char, but why? why not the first char? Does findWithinHorizon(".",0).charAt(0) deletes the char that is assigned to the variable?
And last question: if in the first line the program prompts the user for input why doesn't it do it again in the second line?
Also, a quick recap of the (".",0) would be helpful as well.
Perhaps the piece you are missing is that findWithinHorizon actually takes a regular expression as the String argument. In a regular expression, . matches any character (except a new line).
A call to findWithinHorizon(".", 0) simply finds the next character in the input and advances the Scanner past whatever was found.
So for example,
Scanner in = new Scanner("abc123");
for(;;) {
String found = in.findWithinHorizon(".", 0);
if(found == null) break;
System.out.println(found);
}
the output is:
a
b
c
1
2
3
The reason it does not prompt for input at the second line is that is the way Scanner and System.in work together. They will only block and prompt for input if there is no more existing input to consume. As a short example, try this out:
Scanner in = new Scanner(System.in);
while(true) {
System.out.println(in.findWithinHorizon(".", 0));
}
That will loop infinitely, repeating back whatever you input, character by character. It will only prompt for more when it's done with the prior input. On the first iteration, Scanner will call read on System.in which will block and wait for input. When the input runs out, read will block again.
I will admit, this is a school assignment... But I simply cannot figure out what I am doing wrong.
I have a hash table with an insert function. The following code is supposed to take a line of data from System.in in the format "Long String" (i.e. "32452 John"). The first token must be a Long for the ID number, and it must be followed by a String token for the name. When I run the program and I get to the portion where this must be executed (It is in a switch statement), I entered 'a' and hit enter. The command line immediately reads "Invalid value." (note: not VALUES, as that would mean it hit the nested if statement. It won't let me type in any data. Thank you in advance!
System.out.println("Enter ID and Name.");
//temp to take in the next line entered by the user
//inScan is the Scanner for System.in
temp = inScan.nextLine();
//Create Scanner for the line
Scanner tempScan = new Scanner(temp);
if(tempScan.hasNextLong()){
thisID = tempScan.nextLong();
if((tempScan.hasNext()) && (thisID>0)){
thisName = tempScan.next();
//The data will only be inserted if both segments of data are entered
myTable.insert(new Student(thisID, thisName));
}else{
System.out.println("Invalid values.");
}
}else{
System.out.println("Invalid value.");
}
Why do you need the second Scanner?
Example
String input = scanner.nextLine();
String[] tokens = input.split(" ");
Long id = Long.parseLong(tokens[0]);
String name = tokens[1];
And if you wanted to add your validation:
String input = scanner.nextLine();
if(input.contains(" ")) {
// You know there's a space in it.
String[] tokens = input.split(" ");
if(tokens.length == 2) {
// You know it's a value, followed by a space, followed by a value.
if(tokens[0].matches("[0-9]+")) {
// You know it only contains numbers.
Long id = Long.parseLong(tokens[0]);
}
}
}
I've not run it, but i guess your problem is that when you enter the text 'a' and hit enter, this line is false:
if(tempScan.hasNextLong()){
as you haven't entered a number. hence why it drops to the next block. If you enter something numerical first, i suspect your code with work. you probably need to add a 'while' loop around it, to run until it gets a number.
You already have a Scanner which reads from System.in, there's no need for another one. The second one you've made is a scanner for a String, which will never have a nextLong as it has nothing to scan after your String.
I won't write any code for you as this is homework, but stick to your original scanner when checking for user input instead.
I am expecting input with the scanner until there is nothing (i.e. when user enters a blank line). How do I achieve this?
I tried:
while (scanner.hasNext()) {
// process input
}
But that will get me stuck in the loop
Here's a way:
Scanner keyboard = new Scanner(System.in);
String line = null;
while(!(line = keyboard.nextLine()).isEmpty()) {
String[] values = line.split("\\s+");
System.out.print("entered: " + Arrays.toString(values) + "\n");
}
System.out.print("Bye!");
From http://www.java-made-easy.com/java-scanner-help.html:
Q: What happens if I scan a blank line with Java's Scanner?
A: It depends. If you're using nextLine(), a blank line will be read
in as an empty String. This means that if you were to store the blank
line in a String variable, the variable would hold "". It will NOT
store " " or however many spaces were placed. If you're using next(),
then it will not read blank lines at all. They are completely skipped.
My guess is that nextLine() will still trigger on a blank line, since technically the Scanner will have the empty String "". So, you could check if s.nextLine().equals("")
The problem with the suggestions to use scanner.nextLine() is that it actually returns the next line as a String. That means that any text that is there gets consumed. If you are interested in scanning the contents of that line… well, too bad! You would have to parse the contents of the returned String yourself.
A better way would be to use
while (scanner.findInLine("(?=\\S)") != null) {
// Process the line here…
…
// After processing this line, advance to the next line (unless at EOF)
if (scanner.hasNextLine()) {
scanner.nextLine();
} else {
break;
}
}
Since (?=\S) is a zero-width lookahead assertion, it will never consume any input. If it finds any non-whitespace text in the current line, it will execute the loop body.
You could omit the else break; if you are certain that the loop body will have consumed all non-whitespace text in that line already.
Scanner key = new Scanner(new File("data.txt"));
String data = "";
while(key.hasNextLine()){
String nextLine = key.nextLine();
data += nextLine.equals("") ? "\n" :nextLine;
}
System.out.println(data);
AlexFZ is right, scanner.hasNext() will always be true and loop doesn't end, because there is always string input even though it is empty "".
I had a same problem and i solved it like this:
do{
// process input
}while(line.length()!=0);
I think do-while will fit here better becasue you have to evaluate input after user has entered it.