Java Scanner hasNextInt() causing infinite loop - java

What I am trying to do is have the user enter a lot of numbers and then hit enter, and then store all those numbers onto a stack at once. My thought was to use a loop to go through all the numbers and push them onto the stack like so:
Stack<Integer> mainBin = new Stack<Integer>();
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextInt()) {
mainBin.push(scanner.nextInt());
}
However, even after I press enter many times without entering anything new, it still stays in the loop. Any suggestions?

Scanner.hasNextInt() skips over whitespace to find the next token. So it reads and skips over all your Enter presses. Then it waits for more input, because there may be more input coming.
In a Linux terminal, you can press Ctrl-D (maybe Cmd-D on OS X?) to send an end-of-file marker, which tells the application that there is no more input coming (this should be done at the start of a line). This answer suggests that Ctrl-Z is the equivalent in Windows' command prompt.
Alternatively, you could have some special input that your application reads. #phatfingers commented that you could specify the number of values to read as the very first input. You could also have a special value to signify the end (0 or -1 are common choices, based on the application's needs), or maybe even use a non-numeric token like "end".

Your example uses scanner.hasNext(). Use scanner.hasNextInt() instead.

Related

Is there a way to exit a while loop by reading an empty line with nextLine()? (Java)

For an assignment I need to use a scanner to read an unspecified amount of inputs, and have a corresponding output as a response. In order to keep taking inputs I used the while loop:
while (!(readLine = scanner.nextLine()).equals(""))
The final entry ends with a "next line" so the scanner should be reading nothing, but the loop doesn't end until I press the enter key manually. Any insight on the cause?
Note: An example of the input that's going in is as follows
name specific_string1 specific_string2
command1 name specific_string2
command2 name
command3 name
I take out the first word from the string in order to use the command in a switch statement contained inside the loop, while the name and specific_strings are stored in variables. The nextLine() reads these line-by-line, but won't exit on its own.
The final entry ends with a "next line" so the scanner should be reading nothing, but the loop doesn't end until I press the enter key manually.
That is expected behavior. The way that the operating system (and Java) knows that you have finished entering characters in a line is when you press ENTER. Unless / until you type ENTER, you could type other characters .... making the line non-empty. The ENTER key says "I, the user, have finished this line".
For the record, scanner.nextLine() can return null, so
(readLine = scanner.nextLine()).equals("")
could throw an NPE. When does the nextLine() return null? When the Scanner reaches the end of stream. How do you signal end-of-stream from a console? By typing ^D (on Linux / MacOS) or ^Z (on Windows).
There may be an answer to your conundrum in the above ...

Java scanner.hasNextInt() explanation?

I need explanation about how does scanner's hasNextInt() works. In next example:
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
boolean foo = sc.hasNextBoolean();
System.out.println(sc.nextLine());
}
when program gets to hasNextBoolean(), it waits for my input. Then I press Enter for newline and type true and press Enter again,so the buffer looks like this: [ \n true \n ].
Now the pointer is on word true, and so foo becomes true. But then, the pointer should still be hanging on true, and when next line comes, program should print true, but what happens is that it just prints newline. Why is that case, may I ask?
On the other hand, doing same thing but using nextInt(), works the way that i expected:
public static void main(String[] args) {
Scanner skener = new Scanner(System.in);
try{
int stagod = skener.nextInt();}
catch(Exception e){
System.out.println(skener.nextLine());}
}
Here when program come to skener.nextInt(), I press Enter then type A then press Enter, so the buffer looks like this: [ \n A \n ].
And now, after catching the exception, pointer stays on A and System.out.println(skener.nextLine()); prints A.
sc.hasNextBoolean() is working just fine. The problem is that you failed to account for sc.hasNextBoolean() not advancing past the input that it reads.
sc.hasNextBoolean() reads the input but does not advance past it. So after that call, the input buffer would be "\n", one line. sc.nextLine() DOES advance the scanner past the input after reading it. But in this case, it also waits for the user to enter another line. For you, that would be "true\n" which would make the buffer "\ntrue\n" as expected. But the buffer is 2 lines long. sc.nextLine() only reads one line (the next line). That next line is "\n", it's just a line break. After the System.out.println() call. There is still data in the buffer, which is now "true\n". There's still one line left.
You will find that if you add one more System.out.println(sc.nextLine()), your code will work as expected.
The reason why sc.nextInt() works is because it DOES advance the scanner past the input it reads. It waits for a line of input and then reads it. At this point, the buffer is "\n". But then it also advances past that input that it just read, so the buffer is now empty. The next time you call sc.nextLine(), the scanner is at the position before the line you type, rather than a line behind. So you only need one call to sc.nextLine().
The key to your problem is not that the Scanner methods aren't working as expected. Your problem is simply that your failed to consider that one minor, but crucial, detail about the Scanner.hasNextBoolean() method. There's little things in the documentation like that which can make or break a program. Next time, just remember to read the full documentation of the method you are using before you implement it.

How to take exactly one character input and show output as soon as character is typed?

The thing is to take exactly one character as input and output should be presented without hitting return as soon as a character is typed onto the console.
char a;
Scanner s = new Scanner(System.in);
a = s.next().charAt(0);
I tried this but it still asked for the return key for output.
If your program must be console based, you have to switch your terminal out of line mode into character mode, and remember to restore it before your program quits. There is no portable way to do this across operating systems.
Here is an article on
Non-blocking console input that will provide more details

java calculator randomly outputted line

So I've just started java with a tiny bit of experience from a few other languages. I tried to make this basic calculator and had a lot of problems but managed to resolve most of them. The last thing that I can't seem to understand is a randomly triggered "This is an invalid input", every time my program runs once. "..." refers to irrelevant code. Everything else seems to work fine. Thanks in advance!
import java.util.Scanner;
public class Calc {
...
System.out.println("Would you like to use the calculator?(Y/N)");
while(use){
String usage=in.nextLine().toLowerCase();
if(usage.equals("n")){use=false;}
//input
//operations
else if(usage.equals("y")){
...(calculator code)
System.out.println("Continue use? (Y/N)");
}
else {System.out.println("That is not a valid input");}
}
}
}
After running my code a few times, my output is
Would you like to use the calculator?(Y/N)
Y
Please input an operation: +,-,*,/,%, ^, or root
+
Calculator: Please input your first number.
1
Now enter your second number.
2
Calculating
3.0
Continue use? (Y/N)
That is not a valid input <-- right there is the confusing part, why is that triggered?
Y
Please input an operation: +,-,*,/,%, ^, or root
Full code is on pastebin, if you somehow need it. http://pastebin.com/Qee2Hxe3
I checked the full code, and right before the loop first reiterates, there is a call to in.nextDouble(), this method reads a double but does not consume the line end, which makes the next in.readLine() return \n immidiately and the succeeding test fails.
A simple solution is to manually consume the line-end:
System.out.println(ans);
System.out.println("Continue use? (Y/N)");
in.nextLine();
I tested your code and found that a solution is to declare your scanner inside your while loop, like so:
while (use) {
Scanner in = new Scanner(System.in);
String usage = in.nextLine().toLowerCase();
Here's what the problem is: first, you are entering your while loop, and usage is set equal to in.nextLine(). Since there is no next line, it waits for you to enter one. You enter yes, after which you enter your formula. Then it returns the answer, and goes back to the top of the while loop. Once again, usage is set to equal in.nextLine, but there is already a next line (a blank one) and so usage is set to equal an empty String ("") which is neither "y" or "n". Then it immediately goes to the "else" option at the end and prints the "invalid" message.
Re-assigning your scanner through each iteration of your while loop fixes this problem.
The last input you read in your code when calculating is this:
num2=in.nextDouble();
This reads the next characters and convert it to a double. However when you input your number, you also hit enter.
This means that after the double is read, there is still a newline character left in the input buffer.
As the code goes back to the String usage=in.nextLine().toLowerCase(); , you will now read this newline.
You could just ignore empty input, by e.g. doing
String usage=in.nextLine().toLowerCase().trim();
if (usage.isEmpty()) {
continue;
}

Java Scanner, taking user input from console into array list as separate words

I am trying to read the user input from the console directly into an array list, separated by each word or entity that has whitespace on either side (the default behavior). The problem is I am stuck inside of a while loop. Scanner.next() keeps waiting for more input, though I know I want to stop feeding input after the user presses return:
Scanner input = new Scanner(System.in);
System.out.print("Enter a sentence: ");
do {
if (words.add(input.next());
} while (input.hasNext());
System.out.println(words);
I input a line, except I will have to press CTRL-D to terminate it (IE. signal the end of input). I just want to automatically end it when the return '\n' character is pressed at the end of the sentence.
It may be simpler to use split for what you want.
// read a line, split into words and add them to a collection.
words.addAll(Arrays.asList(input.nextLine().split("\\s+")));
You could always use the Console class, like this:
Console console = System.console();
System.out.print("Enter a sentence: ");
List<String> words = Arrays.asList(console.readLine().split("\\s+"));
System.out.println(words);
The readline() method should take care of the \n issue.
If you require a Scanner for the type reading capabilities, you can mix both classes:
Scanner scanner = new Scanner(console.reader());
Hope this helps!
You could call input.hasNextLine and input.nextLine to get a line, and then create a new Scanner for the line you got and use the code that you have now. Not the cheapest solution, but an easy way to implement it until you come up with a better one :-)

Categories