Java scanner - can't read user input - java

I want to read user input like: 11 12 13 14 15 16
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
System.out.println(sc.next());
}
System.out.println("Test");
but it newer goes out of while loop and prints "Test".
How could i read that input?

The method hasNext() works like this:
If it sees the end of the file, it returns false;
If it sees another valid, non-whitespace input, it returns true;
If neither of the above is true, it waits for the next input the user is going to enter, and doesn't return until he does.
Usually, if you use Scanner for files, such a loop will work correctly, because a file has a definite end, and it usually doesn't get stuck waiting for more input.
But when you are working with console input (System.in, not redirected), then usually the user does not send the end-of-file signal. He just presses Return, and so, hasNext() sits and waits to see if the user will enter more input on the next line and so on.
There are two general ways to deal with this:
The user has to actually terminate the input. After you finish entering all your numbers and press Return, you also need to send the end-of-file sequence, which is usually ctrlD or ctrlZ.
If you do that, you will not be able to enter any more input to that program.
The program tells the user to enter some particular value that will tell it that the input is over. For example, the string "DONE". When you do that, you have to change the loop to something like:
String nextInput;
while( sc.hasNext() && ! (nextInput = sc.next()).equals( "DONE" ) ){
System.out.println(nextInput);
}

You can break the loop depending whether you want to quit or not E.g.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String next = sc.next();
if (next.equals("q")) { //if user press q then break the loop
break;
}
System.out.println(next);
}
System.out.println("Test");
}

Use api like:
while(sc.hasNextInt()){
int aba= sc.nextInt();
if (aba == 0) {//or even non numeric value here would let this loop exit
break;
}
}
So you need to enter 0 or even in other way enter non numeric value inorder to come out of loop. nextLine method will read whole line just once and then you will need to parse it and then convert to integer so it's good to use sc.nextInt which will do the work for you.

Related

hasNextInt won't return false and exit the loop

I'm trying to put user input into an array but the hasNextInt() method will not return false and stop the input.
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
int target = in.nextInt();
while(in.hasNextInt()) {
weights.insert(in.nextInt());
}
recKnapSack(target, 0);
}
Scanner.hasNextInt() will return false when it encounters a non-integer character in its buffer.
However, it may strip out whitespace when it's reading prompts. So Space+Enter or Enter will most likely not stop the loop. But any other character will.
Since you'd like to input any number of ints, you must instruct the user on what to type when they're done. In fact, if you're writing a console application, it's a good idea to always explain WHY a program is waiting for input.
Any non-integer will stop the loop condition. In this case the syntax will work as-is, the user just needs some instruction:
System.out.println("Please enter the target");
int target = in.nextInt();
System.out.println("Enter weights. Type 'X' to stop");
while(in.hasNextInt()) {

How to skip control when we are using scanner readLine() when user is nothing entered from keyboard?

My code is :
System.out.print("press key Y or N to run the test");
Scanner sc = new Scanner(System.in);
String input = null;
input = sc.nextLine();
There is nothing you can do. nextLine() waits for the user to press "Enter" on the keyboard; it will block forever until that happens.
If you really want that things happen "automatically", you will need a more complex solution; for example you can wait for user input in a separate thread; and if there is no input after a given amount of time, your other thread can start doing "whatever" "automatically".
Please tell the user to hit return after his input and check for empty lines like this:
if("".equals(input)){ //skip control
}
else{ //do something on input
}

How do I ensure that Scanner hasNextInt() asks for new input?

New programmer here. This is probably a really basic question, but it's stumping me nevertheless.
What I'm trying to do is write a method that supplies only one integer input so I can use that input in my main program without having to mess around with non-integer inputs. However, even writing the method to do that in its own method seems to be problematic.
public static int goodInput () {
Scanner input = new Scanner (System.in); //construct scanner
boolean test = input.hasNextInt(); //set a sentinel value
while (test == false) { //enter a loop until I actually get an integer
System.out.println("Integers only please"); //tell user to give me an integer
test = input.hasNextInt(); //get new input, see if it's an integer
}
int finalInput = input.nextInt(); //once i have an integer, set it to a variable
input.close(); //closing scanner
return finalInput; //return my integer so I don't have to mess around with hasNextInt over there
}
This seems to be broken in multiple levels, but I'm not really sure why.
If I enter an integer value like 0 or 1 when I'm first asked for input, it should skip the loop entirely. But, instead, it enters the loop, and prints "Integers only please". Even worse, it doesn't actually ask for input while I'm in there, and just prints that line repeatedly.
I understand the latter problem is probably due to token issues, but I'm not necessarily sure how to solve them; closing and then reopening the scanner gets Eclipse to bug me over "duplicate objects", simply assigning the old input to a garbage String variable that is never used tells me that "No line was found" at runtime, and I'm not experienced enough to think of other ways to get new input.
Even once that's solved, I need to find some way to avoid entering the loop in the case of having an integer. I don't really understand why integer inputs inter the loop to begin with, so I'm not sure how this would be possible.
Please help? Sorry if this is an old question; tried looking at past questions but none of them seem to have the same problem that I have.
You were close: this works fine for me:
Scanner input = new Scanner(System.in); //construct scanner
while(!input.hasNextInt()) {
input.next(); // next input is not an int, so consume it and move on
}
int finalInput = input.nextInt();
input.close(); //closing scanner
System.out.println("finalInput: " + finalInput);
By calling input.next() in your while loop, you consume the non-integer content and try again, and again, until the next input is an int.
//while (test == false) { // Line #1
while (!test) { /* Better notation */ // Line #2
System.out.println("Integers only please"); // Line #3
test = input.hasNextInt(); // Line #4
} // Line #5
The problem is that in line #4 above, input.hasNextInt() only tests if an integer is inputted, and does not ask for a new integer. If the user inputs something other than an integer, hasNextInt() returns false and you cannot ask for nextInt(), because then an InputMismatchException is thrown, since the Scanner is still expecting an integer.
You must use next() instead of nextInt():
while (!input.hasNextInt()) {
input.next();
// That will 'consume' the result, but doesn't use it.
}
int result = input.nextInt();
input.close();
return result;

How does writing a new scanner in a while loop stop an otherwise infinite loop?

So I am trying to stop an error from happening if the user inputs a number other than 1,2,3, so I created a while loop to make the program keep asking the user for a new number if their input is outside 1,2,3.
Before I didn't have the
Scanner user1 = new Scanner(System.in);
input = user1.nextInt();
lines, and the while loop kept running infinitely. But now the code does what I want, it stops and evaluates the new user input for as many times as the input is wrong (I've entered 3,6,7 wrong values before a correct one and it works every time).
My question is, how does the scanner stop the infinite loop? Does the Scanner impletmentation cause the computer to wait for a user input before it continues, and so because of this it goes back to evaluate it continuously, instead of infinitely printing out "I'm sorry that's not a valid input..." ? I just want to be sure I know WHY it's stopping.
Scanner user = new Scanner(System.in);
System.out.println("Hello, what would you like to do?" + "\n" + "1. Search" + "\n" + "2. Add new instructor" + "\n" + "3. Remove Intsructor");
int input = user.nextInt();
boolean valid = false;
while(valid == false)
{
if(input<3 && input>=1)
{
valid = true;
}
else
{
System.out.println("I'm sorry, that's not a valid input, please enter 1, 2, or 3.");
Scanner user1 = new Scanner(System.in);
input = user1.nextInt();
}
It stops the loop by waiting. nextInt() is a blocking method, meaning when you call it, the thread that called it will wait until that method either returns a value, or the reason for the block has finished.
When you call nextInt(), your thread haults, and waits until something comes through System.in. Once something comes in, the method returns the value.
If you put scanner.nextInt() inside of of your loop, then each loop iteration will wait for user input
Scanner scanner = new Scanner(System.in);
boolean valid = true;
while(valid) {
switch(scanner.nextInt()) {
case 1:
case 2:
valid = false; //if nextInt() is 1 or 2
break;
default: //anything else
break;
}
}
Consider this:
Your loop stops only when valid is set to true
valid is set to true only when input is 1 or 2
If input is outside the valid range, valid does not change
If input is outside the range upon the first entry into the loop, the only way to stop the loop is to change the value of input.
Without the two lines that you added, i.e. without
Scanner user1 = new Scanner(System.in);
input = user1.nextInt();
the loop does not change input. Therefore, if the loop is not exited right away, it stays infinite.
Note that you do not need to create a new scanner - you can read from the one that you created before the loop, i.e.
input = user.nextInt();
Also note that calling nextInt() without calling hasNextInt() may produce an exception.

Code in while loop doesn't execute

I am playing with Java and want to do a simple while loop that keeps going until the user presses ctrl+z.
I have something like this:
public static void main(String[] args) {
//declare vars
boolean isEvenResult;
int num;
//create objects
Scanner input = new Scanner(System.in);
EvenTester app = new EvenTester();
//input user number
System.out.print("Please enter a number: ");
num = input.nextInt();
while() {
//call methods
isEvenResult = app.isEven(num);
if(isEvenResult) {
System.out.printf("%d is even", num);
} else {
System.out.printf("%d is odd", num);
}
}//end while loop
}//end main
I tried while( input.hasNext() ) { ... but the code inside the while loop wouldn't execute.
//input user number
System.out.print("Please enter a number: ");
do {
try {
num = input.nextInt();
} catch (Exception e) {
break;
}
// call methods
isEvenResult = app.isEven(num);
if (isEvenResult) {
System.out.printf("%d is even", num);
} else {
System.out.printf("%d is odd", num);
}
} while (true);
When the user writes something non-numeric, the loop breaks.
while (num != 'z')
Although if you are expecting a 'z' why are doing input.getInt()?
You may want to check out the Console class too.
If you want to loop until the user has to force break via Ctrl+Z, then just do while(true). But you want your nextInt() to be inside the loop, and maybe also your prompting statement.
TrueSoft's solution is dead on. The reasons it may not be working for the asker is are kinda outside the scope of the program.
The program works for me: I'm running it under Linux and enter Ctrl-D as the first thing on a line. Ctrl-D is end-of-file for Linux the same way that Ctrl-Z is for Windows. Program stops dead in its tracks, perfectly.
The Windows console (the black DOS box, whatever you want to call it) has a wrinkle: It reads input line-by-line. It won't see the Ctrl-Z until it's read the line, so it needs an Enter keyin before it will see the Ctrl-Z.
I'm unwilling to fire up Windows just to try this, but my guess is that CTRL-Z followed by the Enter key (just like after the number entries) should cause the program to stop cleanly.
There are system-y ways to make a Java program work on a character-by-character basis so you can handle any characters directly and respond immediately to Ctrl-Z. But that's advanced stuff and doesn't belong in a simple programming exercise like this. I think Ctrl-Z / Enter is an acceptable way to have the program end.
You need to implement KeyBindings. Then you can make the determination to exit based off of what keys were pressed.
you are doing the input outside the loop,and it will run for only once.
System.out.print("Please enter a number: ");
num = input.nextInt();
Put your above code inside the loop.
Since you are having a system out inside the loop you will also come to know whether the control went inside the loop, obviously it should.
Also, try
while(true)
I wonder if while() alone is working.
This looks like Exercise 6.16 out of Deitel's book Java How to Program, 9th Edition.
The CTRL-Z charcter does, indeed, end input on a Windows platform just as CTRL-D ends input on most any UNIX or Linux platform.
Also, there are logic errors in the construction of the program that indicate Scanner methods and the System.in byte stream (i.e. the standard input from the console) are not well understood.
In your posted program, the statement:
num = input.nextInt();
executes unconditionally. It will block execution until some kind of input is received. If the input is not an integer, it will throw an exception. If the input received is an integer, then num will be assigned the integer value and the integer in the input stream (input) will be discarded from the input stream. There may be remainaing stuff on the input line up to the end of line, depending on what the user typed in before hitting the enter key that ended the input line and placed it into the System.in byte stream that Scanner is scanning.
If you were to leave your program as written except for putting input.hasNext() into the while statement's test condition, it would block until more input was in the input stream after the integer that nextInt() processed.
Some answer(s) suggest using KeyBindings as a solution. Whilst that may work, it gets into waiting for keypress events at nearly the hardware level and is NOT friendly to platform independence. It is a potential rabbit-hole into Alice's Wonderland for having to figure out all kinds of event processing and the code having to know what platform it is running on. Using the hasNext() boolean false return to indicate the end of the input stream should work on any platform and will avoid potentially non-portable gee-whiz code for processing the keyboard and key presses at nearly the hardware event level.
The following program is one that does what you (and the exercise) intended and will end the input if the user presses CTRL-Z on a Windows platform or a CTRL-D on a UNIX/Linux platform without you having to determine the platform on which the code is executing.
// Exercise 6.16: EvenOrOddTest.java
// Write a method isEven that uses the remainder operator (%)
// to determine whether an integer is even. The method should
// take an integer argument and return true if the integer is
// even and false otherwise. Incorporate this method into an
// application that inputs a sequence of integers (one at a time)
// and determines whether each is even or odd.
import java.util.Scanner;
public class EvenOrOddTest {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int integer;
System.out.println("Odd even integer test.");
System.out.printf("Input CTRL-Z on Windows or CTRL-D on UNIX/Linux to end input\n"
+ "or an integer between values\n"
+ "%d and %d\n"
+ "to test whether it is odd or even: ",
Integer.MIN_VALUE, Integer.MAX_VALUE);
// the input.hasNext() will block until
// some kind of input, even a CTRL-Z,
// arrives in the stream
// the body of the while loop will execute
// every time input appears for as long as the input
// is not a CTRL-Z
while (input.hasNext()) { // repeat until end of input
// prompt user
// now see if the input we did get is an integer
if (input.hasNextInt()) { // we got an integer...
integer = input.nextInt();
System.out.printf("\n%d is "
+ (EvenOrOdd.isEven(integer) ? "even.\n\n" : "odd.\n\n"), integer);
} else { // we got a non-integer one too large for int
System.out.printf("\nInput %s invalid! Try again...\n\n", input.next());
} // end if...else
// white space (i.e. spaces and tabs) are separators
// next and nextInt get only to the first separator
// so it is possible for the user to enter an integer
// followed by tabs and/or spaces followed by more
// input, integer or not up to the end of the input line
// input.nextLine() flushes everything not processed
// by the nextInt() or next() to the input line end
// won't block execution waiting for input
// if there is nothing left on the input line
input.nextLine();
// prompt for user input again
System.out.printf("Input CTRL-Z to end input\n"
+ "or an integer between values\n"
+ "%d and %d\n"
+ "to test whether it is odd or even: ",
Integer.MIN_VALUE, Integer.MAX_VALUE);
} // end while
} // end main
static boolean isEven(int integer) {
// integer modulus 2 is zero when integer is even
return ((integer % 2) == 0);
} // end isEven
} // end class EvenOrOddTest

Categories

Resources