I need to do an assignment where I have to write a while loop with a condition like:
while (not end of stream) {
}
I'm confused about the "not end of stream part". How do I make it so it stop reading when there is no integer input in the console? It will be entered like this: 1 2 3 4 5 6 7 8 9.
I am using the Scanner class my code is something like this:
Scanner myScanner = new Scanner(System.in);
int inputValue = userInput.nextInt();
while(not end of stream) {
if (.......) {
....
} else {
....
}
}
Thanks!
Don't let the word stream confuse you, when reading from System.in, there is no continuous 'flow' of numbers coming.. The user can type what ever he wants to and as long as he wants to. Until he hits 'Enter' nothing will happen.
That said, the scenario is more like this:
1 user types 71 2 30 5 1 and hits Enter
2 userInput.nextInt(); will return the first int it finds so here 71
3 now you could do something like this: [EDITED]
public static void main(String[] args) {
System.out.print(">");
Scanner userInput = new Scanner(System.in);
int inputValue = userInput.nextInt();
while (userInput.hasNextInt()) {
System.out.println("you just wrote: " + userInput.nextInt());
}
userInput.close();
}
So until the scanner doesn't find any input that is not an int the loop will continue. In other words, when the user types for example an 'b' the loop terminates.
Now it all depends on what you have to do in your while-loop. You could test for userInput.hasNext() to see if anything comes, or userInput.nextLine() which will wait for an Enter .. or what ever you need.
When I run the above main and type in:[ 1 Enter 2 Enter 3 Enter 4 Enter a Enter ], this is the output:
>1 // <-- this is the number before the while loop
2 // <-- now another number
you just wrote: 2 // <-- and the while loop makes its first iteration
3 // <-- then it waits for you to input the 3rd number
you just wrote: 3 // <-- to make its next iteration
4 // <-- and the 4th
you just wrote: 4 // <-- 4th iteration
a // <-- until you type something else
// end of program
The user always has to hit Enter – otherwise the operation system won't give the typed input to the Java program. This has to do with the settings of the Shell / Console that your operation system provides for the Java program to run. So, Java won't see anything of the input until you hit enter.
Related
I'm new to java and am trying to validate numbers being entered into the console. I want an integer, but I know if a letter is entered for example an error would occur, so I thought I'd use try & catch. This works if try and do it first time round, but I want to loop through until the user inputs a valid integer. Got this working, but when I get a valid number and print out the number I get a list of all attempts.... Hope this makes sense
import java.util.Scanner;
public class ConvertStringInt {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int i = 0;
System.out.print("Enter a whole number: ");
try {
i = sc.nextInt();
} catch (Exception e){
System.out.println("Error");
main(args);
}
System.out.println(i);
}
}
Here is the output from the console....
Enter a whole number: a
Error
Enter a whole number: d
Error
Enter a whole number: 2.0
Error Enter a whole number: 1
1
0
0
0
Could somebody please explain this?
Thanks in advance
Neil
You are seeing outputs for each input because you call main recursively. If you immediately type a correct int, the flow is this:
main
ask for input -> int
print i (1)
But in your case the input is not an int. This is what happens: you type the first input, it fails. You do not print yet because you first call main again, asking for the next input. Only when you get a correct int you print, and then finish and allow the previous main-execution to finish by printing, which then allows the previous... and so on:
main(args)
ask for input -> a !int
main(args)
ask for input -> d !int
main(args)
ask for input -> 2.0 !int
main(args)
ask for input -> 1 int
print 1 (1)
print 0 (2.0)
print 0 (d)
print 0 (a)
Look at Ravi's answer for a proper way to repeatedly ask for input without using try/catch (which is discouraged).
You could check for integer token in loop
while (!sc.hasNextInt()) // loop until next token is integer
{
// do something or print error
System.out.println(sc.next() +"is not number");
}
i = sc.nextInt();
I'm working on a question where I need to store and use the data given by the user. The data given by the user is usually in the below format.
Input:
5
0
4 5 1 0
1 0
5 3 0
3 0
Let's say the user enters a value for 'N' where N>1 and N<500.
In the above example, N=5;
so now, there will be N lines available for the user to enter numbers between 1 and 100 again.
According to the above example, the next N (here N=5) lines contains numbers given randomly by the user. Each line can contain one number or more than 1 which are separated by the spaces. But the code should break after 5 lines are finished. The user should not be able to enter any more data after N lines.
My question is, how can i take the input from the user where there should be N lines and each line can store one or more than one value (<=100)(each value separated by spaces) and should end after the N lines are finished.
I'm not able to come up with any solution. kindly help me on giving me some ideas on how can i go about with it. Thanks.
You can use this for example
public static void main(String[] args)
{
Scanner reader = new Scanner(System.in);
String line = reader.nextLine();
while (!line.equals("")) {
// what ever you has to do
System.out.println(line);
line = reader.nextLine();
}
}
This code read lines until the user press enter and dont have an input
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.
I'm making a console-based game of black jack that prompts the user asking him/her if he/she wants to: 'h' for hit, 's' for stay, or 'q' for quit. I'm using the Scanner class to receive input from the user in a while loop. The code works the first time it prompts the user and receives input, but it never works the second time. After the second prompt comes up, no matter what the user types, the program just waits and does nothing even though it's still running. I've been trying to get this to work for hours and have read the Java Docs, many SO questions, etc. Here's the relevant code:
public void gameloop() {
while (thedeck.cards.size() >= 1) {
prompt();
}
}
public void prompt() {
String command = "";
Boolean invalid = true;
System.out.println("Enter a command - h for hit, s for stay, q for quit: ");
Scanner scanner = new Scanner(System.in);
while (invalid) {
if (scanner.hasNext()) {
command = scanner.next();
if (command.trim().equals("h")) {
deal();
invalid = false;
} else if (command.trim().equals("s")) {
dealerturn();
invalid = false;
} else if (command.trim().equals("q")) {
invalid = false;
System.exit(0);
} else {
System.out.println("Invalid input");
scanner.next();
}
}
}
scanner.close();
}
Here's what the code outputs:
Dealer has shuffled the deck.
Dealer deals the cards.
Player's hand:
Three of Clubs: 3
Five of Clubs: 5
Enter a command - h for hit, s for stay, q for quit:
h
Dealer deals you a card:
Player's hand:
Three of Clubs: 3
Five of Clubs: 5
Queen of Hearts: 10
Enter a command - h for hit, s for stay, q for quit:
h (Program just stops here, you can keep entering characters,
but it does nothing even though the code is still running)
Any idea as to what's going wrong would be greatly appreciated. I also realize the while loop is a little ugly, but I just want to get this program in working condition before I start to revamp any code.
From the documentation for Scanner.close:
When a Scanner is closed, it will close its input source if the source implements the Closeable interface.
Here you close your scanner, and this causes System.In to be closed, which means you can't read any more input:
scanner.close();
It is better to open the scanner once and reuse it. Close it only when are sure you have finished reading all input, or are closing your application.
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