I'm trying to write a very simple number guessing game (code is below). After 1 round is finished, the user is supposed to be able to decide whether he/she wants to play another round or not. Problem is, the program always skips the last question (never letting the user answer 'y' or otherwise. What am I missing here? Is there something about java.util.Scanner I don't know about?
import java.util.Random;
import java.util.Scanner;
public class GuessNum {
public GuessNum() {
int numRandom = 0;
int numGuess;
int life = 5;
String want = "";
Random rand = new Random();
Scanner scan = new Scanner(System.in);
do {
int lifeLeft = 5;
numRandom = rand.nextInt(9)+1;
System.out.print("\nGuess the Number [1..10]\n");
System.out.print("===================\n");
System.out.print("You have " + lifeLeft + " chances.\n");
do {
do {
System.out.print("What number do I have in mind: ");
numGuess = scan.nextInt();
if (numGuess < 1 || numGuess > 10)
System.out.println("Invalid input. Range is 1-10.");
} while (numGuess < 1 || numGuess > 10);
if (numGuess != numRandom && lifeLeft != 0)
System.out.println("Wrong! You only have " + --lifeLeft + " chances left.");
} while (numGuess!=numRandom && lifeLeft > 0);
if (numGuess == numRandom)
System.out.println("Correct! -- in " + (life - lifeLeft) + " guess(es).");
if (lifeLeft == 0) {
System.out.println("You have no more lives..");
System.out.println("This is the number: " + numRandom);
}
System.out.print("\nEnter 'y' if you want to play again or any other character to exit: ");
want = scan.nextLine();
} while (want.equals("y") || want.equals("Y"));
}
public static void main(String[] args) {
new GuessNum();
}
}
Use want = scan.next(); instead of nextLine().
The reason for your problem is that following the preceding nextInt(), you're still on the same line, and nextLine() returns the rest of the current line.
Here's a smallest snippet to reproduce the behavior:
Scanner sc = new Scanner(System.in);
System.out.println("nextInt() = " + sc.nextInt());
System.out.println("nextLine() = " + sc.nextLine());
When you type in, say, 5 and then hit Enter, the output is:
nextInt() = 5
nextLine() =
That is, nextLine() did not block for your input, because the current line still has an empty string remaining.
For comparison, when you type in, say 5 yeah! and then hit Enter, then the output is:
nextInt() = 5
nextLine() = yeah!
Note that " yeah!" actually comes from the same line as the 5. This is exactly as specified in the documentation:
String nextLine(): Advances this scanner past the current line and returns the input that was skipped. This method returns the rest of the current line, excluding any line separator at the end. The position is set to the beginning of the next line.
On half-open ranges
Assuming that the number to guess is between 1 and 10 inclusive, the following code is "wrong":
numRandom = rand.nextInt(9)+1; // this can only be in 1..9 range inclusive!
Here's an excerpt from the documentation of java.util.Random:
int nextInt(int n): Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive)
That is, like a lot of methods in Java's API, Random.nextInt(int) uses the half-open range, with inclusive lower bound and exclusive upper bound.
Related questions
Are upper bounds of indexed ranges always assumed to be exclusive?
Use scan.next()+ scan.nextLine(); instead
eg.
Scanner scan = new Scanner(System.in);
String s = scan.nextLine() +scan.nextLine();
Problem occurs because the last newline character for the last line of input is still queued in the input buffer and the next nextLine() will be reading the remainder of the line (which is empty).
So, when you use next it goes to the next token, then you can get the remaining input using nextLine()
Related
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 2 years ago.
I am feeling quite stupid at this point for not being able to figure out something that is most likely a simple fix. I keep getting the error "Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:68)
at java.base/java.lang.Integer.parseInt(Integer.java:662)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at searchSorting.main(searchSorting.java:15)" after inputting how many numbers I want to input. Others solutions to this problem just don't seem to apply to me somehow. Thanks for the help
import java.util.Scanner;
import java.util.Arrays;
public class searchSorting
{
public static void main (String[]args)
{
String line;
int number, search, item, array[], first, last, middle;
Scanner in = new Scanner(System.in);
System.out.print("How many numbers you want to input?: ");
number = in.nextInt();
array = new int [number];
item = Integer.parseInt(in.nextLine());
double[] values = new double[item];
for (int i = 0; i < values.length; i++) {
System.out.print("Input number " + i + ": ");
values[i] = Double.parseDouble(in.nextLine());
}
for (int index = 0; index < 5; index++)
System.out.print(values[index] + " ");
in.nextLine();
Arrays.sort(values);
System.out.println("Sorted number is: " + Arrays.toString(values));
System.out.println("Enter the number you are looking for?");
search = in.nextInt();
first = 0;
last = (item - 1);
middle = (first + last)/2;
while( first <= last )
{
if ( array[middle] < item )
first = middle + 1;
else if ( array[middle] == item )
{
System.out.println(item + " found at location " + (middle + 1) + ".");
break;
}
else
{
last = middle - 1;
}
middle = (first + last)/2;
}
if ( first > last )
System.out.println(item + " is not found.\n");
}}
For more info check out Scanner and Integer documentation, it's an excellent resource.
Edit: Try removing line 15 and replacing item with number in the next line
You call this:
number = in.nextInt();
Assuming the user types 123 and ENTER, this call consumes the 123 and leaves the input stream positioned before the end-of-line character.
The next relevant code is
item = Integer.parseInt(in.nextLine());
The nextLine call advances the input stream past the end-of-line, returning all characters it passed on the way. Since the ENTER key was pressed immediately after 123, the returned value is the emoty string. Which is not an integer.
You need to review your strategy of sometimes scanning numbers (nextInt) and sometimes scanning rest-of-linr (nextLine). Mixing the two needs to be done quite carefully. You might be better advised to stick to the numerical methods (nextInt/nextDouble).
For example, replacing this
item = Integer.parseInt(in.nextLine());
by this
item = in.nextInt();
automatically handles the line-ending.
From discussion in comments:
I am still confused as to why it's having me input
the value a second time on the next line
Making assumptions about how you modified the code since your initial question: it's because you've written code that reads the number twice:
System.out.print("How many numbers you want to input?: ");
number = in.nextInt(); // **** first input ****
array = new int [number];
item = in.nextDouble(); // **** second input ****
double[] values = new double[item];
Each time you call for in.nextSomething() the Scanner is going to read more input. It should likely just be this:
System.out.print("How many numbers you want to input?: ");
number = in.nextInt();
array = new int [number];
double[] values = new double[number];
I have code that is supposed to guess the user's number and it will narrow its search based on user input. The only issue is that within the while loop, the conditionals are not working with .equals. Instead, it skips to the else even when I type "less than". This is my code below, I am new to java so I might have made a mistake.
package reversedHiLo;
//Import utility
import java.util.*;
public class ReversedHiLo
{
public static void main(String[] args)
{
//create scanner class
Scanner sc = new Scanner(System.in);
System.out.println("Welcome to reverse number guessing game, pick a number between 1 and 100 and type it below:");
int answer = sc.nextInt();
//Create the first guess
int guess = 1 + (int)(100*Math.random());
//Create an array that stores the range of the player's number
int[] range = new int[] {1,100};
//While loop that guesses the number
while(guess != answer)
{
System.out.println("Is your number greater than or less than " + guess + "?" + Arrays.toString(range));
String response = sc.next();
sc.nextLine();
//Conditionals to set the range of the guess
if(response.equals("less than"))
{
range[1] = guess;
}
else
{
range[0] = guess;
}
//Guess a new number based on the range
guess = range[0] + (int)((range[1] - range[0]) * Math.random());
}
//Final print
System.out.println("Your number was " + answer + ".\nThe computer's guess was: " + guess);
//Close scanner
sc.close();
}
}
There are two places where there is a problem:
The first one sc.nextInt() method - which only reads the int
value by keeps current reading buffer on the same line. So to
ignore/skip everything what is after int on the input line (which is
probably \n or \r\n if you only enter the number) you have to
use sc.nextLine().
The second one is sc.next() method - which
only reads first token(or simply word) from your line. That is
probably why you only get "less" value assigned to response
and that will never be .equals to "less than". So you will
have to replace sc.next() one with sc.nextLine() and remove
unnecessary sc.nextLine() from the next line.
Hope this should be clear now and you have a better understanding of what happens when you call these function. If not then I strongly advise you to have a look into Scanner class, read JavaDocs on write multiple tests around it to get a better understanding of what is going on.
If my explanation is still not clear have a look at the code I have modified for you below:
public static void main(String[] args)
{
//create scanner class
Scanner sc = new Scanner(System.in);
System.out.println("Welcome to reverse number guessing game, pick a number between 1 and 100 and type it below:");
int answer = sc.nextInt();
sc.nextLine(); // This one is necessary to ignore everything on the same line as your number was typed in
//Create the first guess
int guess = 1 + (int)(100*Math.random());
//Create an array that stores the range of the player's number
int[] range = new int[] {1,100};
//While loop that guesses the number
while(guess != answer)
{
System.out.println("Is your number greater than or less than " + guess + "?" + Arrays.toString(range));
String response = sc.nextLine(); // This reads the whole input line
//Conditionals to set the range of the guess
if(response.equals("less than"))
{
range[1] = guess;
}
else
{
range[0] = guess;
}
//Guess a new number based on the range
guess = range[0] + (int)((range[1] - range[0]) * Math.random());
}
//Final print
System.out.println("Your number was " + answer + ".\nThe computer's guess was: " + guess);
//Close scanner
sc.close();
}
I have to read the following symbols with Scanner and process them separately.
The input is:
###xx#*
1 -1 -1 4
The first line is the life and food of a game animal, the second row are her moves the - to the left, + to the right
I start with something, but not enough:
Scanner sc = new Scanner(System.in).useDelimiter("\\s*");
while (!sc.hasNext("z")) {
char ch = sc.next().charAt(0);
System.out.print("[" + ch + "] "); // to check what is happening
}
How to read the second row of integers with - and + and then operate with them?
You can use Scanner 's built-in methods like nextInt() and next() also look for something like hasNextInt() it can be usefull.
You can use various scanner class functions to do that. Input is:
1 -1 -1 4
Create two arrays to store characters '-' and '+' and one to store integers
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
if(sc.hasNextInt()){
intArray = sc.nextInt();
}
else charArray = sc.next();
}
You can parse the input character to integer if it parses then you can continue your code if it throws number format exception then you should know input character is not a number.
Scanner sc = new Scanner(System.in).useDelimiter("\\s*");
while (!sc.hasNext("z")) {
char ch = sc.next().charAt(0);
try {
int a = Integer.parseInt(String.valueOf(ch));
switch (a){
case 1:
// your condition
case -1:
// your condition
case -4:
//condition
default:
// your condition
}
}catch (NumberFormatException ex){
System.out.printf("input character is not number");
}
System.out.print("[" + ch + "] ");// to chack what is happening
}
The Java Scanner class has a whole bunch of methods for grabbing and parsing the next part of a string, e.g. next(), nextInt(), nextDouble(), etc.
The code looks like this:
String input = "1 -1 -1 4";
Scanner s = new Scanner(input);
int i1 = s.nextInt();
int i2 = s.nextInt();
int i3 = s.nextInt();
int i4 = s.nextInt();
Will read all four values
as most of the people is saying you can use scanner.nextInt() and about watching if you have to go the left or to the right you have the method Math.signum() which tells you were to go and then you can take the Math.abs() to get the value as an absolute number.
You could read whole line instead read by characters. Then split line into String array which will be contains chars of lines and operate with array. Here the solution of your case line.replaceAll("(-*[\\W\\d\\w])(\\s*)", "$1 ")
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (!sc.hasNext("z")) {
String line = sc.nextLine();
String[] split = line.replaceAll("(-*[\\W\\d\\w])(\\s*)", "$1 ").trim().split(" ");
Arrays.asList(split).forEach(ch -> System.out.print(ch + " "));
}
}
Output:
###xx#*
# # # x x # *
1 -1 -1 4
1 -1 -1 4
I'm prompting a user for a number and am trying to determine the amount of even, odd, and zeros in that number
/* This program will determine and print the number of even, zero, and odd digits in
* an integer
*
* Author: Marco Monreal
* Date: 11/01/2016
*/
import java.util.Scanner;
public class PP5_3
{
public static void main(String[] args)
{
String exit_loop, go_again, user_num, first_char_string;
int odds, evens, zeros;
int first_char; //, second_char, third_char, fourth_char, fifth_char, sixth_char, seventh_char, eighth_char, ninth_char, tenth_char;
Scanner scan = new Scanner (System.in);
evens = 0;
odds = 0;
zeros = 0;
exit_loop = "no"; //initializing while loop
while (exit_loop.equals ("no"))
{
System.out.println ("Choose any number between 0 and 2,147,483,647. Don't include commas please.");
user_num = scan.next ();
I'm getting stuck around this area; "first_char" is not returning the digit value that I want/need.
//assigning a variable to each character of user_num
first_char = user_num.lastIndexOf(0);
/*second_char = user_num.charAt(1);
third_char = user_num.charAt(2);
fourth_char = user_num.charAt(3);
fifth_char = user_num.charAt(4);
sixth_char = user_num.charAt(5);
seventh_char = user_num.charAt(6);
eighth_char = user_num.charAt(7);
ninth_char = user_num.charAt(8);
tenth_char = user_num.charAt(9);*/
//copy every character into a string value
first_char_string = String.valueOf(first_char);
if (first_char == 2 || first_char == 4 || first_char == 6 || first_char == 8)
{
evens++;
}
else if (first_char_string.equals("1") || first_char_string.equals("3") || first_char_string.equals("5") || first_char_string.equals("7") ||
first_char_string.equals("9"))
{
odds++;
}
else
zeros++;
} //ends while loop
System.out.println ("There are " +evens+ " even numbers, " +odds+ " odd numbers, and " +zeros+ "zeros in ");
scan.close ();
} //ends main method
} //ends class
Hi take a look on this line:
user_num = scan.next (); // this will scan your user input, but does not jump to the next line
you might want to use:
user_num = scan.nextLine();
Also you made a mistake in your lastIndexOf(char) method.
This method expects a char. you supply this method an int e.g:
first_char = user_num.lastIndexOf(0);
this works because java interprets your number a an ASCI-number. the char representated by ASCI "0" is null. What you want to do is search for the character '0'. Like the following:
first_char = user_num.lastIndexOf('0');
The same for your equalisations:
first_char == 2 ---> first_char == '2';
Another notice. Please use camel case istead of underscores. instead of user_num you should write userNum. Thats the standard.
Yet another notice. The lastIndexOf() method will return the nummber of the last occurence of the parameter. e.g:
String test = "hello test";
test.lastIndexOf(e); // this will return 7 for it is the number ofthe last occurence of 'e'
I think yu want to use charAt(0) this returns the charactere at specified position
Last Notice. why are you comparing char values representing numbers ?
why not do the following:
int userNum = Integer.valueOf(yourCharHere).
Update
If I understood your comment correctly the your 'X' in the snippet below is defined by the user
first_char = userNum.charAt(X);
If I get you right you have a problem because you dont know how long the input of the user is. Instead of assigning the individual numers to variables I would do the following:
//Parsing your String into a int
int userNum = Integer.valueOf(yourUserInputHere);
Arraylist singleDigits = new ArrayList()<>;
//This goes through all digits of your number starting with the last digits
while (userNum > 0) {
singleDigits.add( userNum % 10);
userNum = userNum / 10;
}
//Reverses your list of digits
Collections.reverse(singleDigits);
Example input: 13467
your List should look like: [1],[3],[4],[6],[7]
This enables you to get the single digits by calling:
singleDigits.get(0) -> [1];
singleDigits.get(3) -> [6];
...
I hope that helps
First create sets that are containing odd/even/zero numbers:
Set<Integer> odds = "13579".chars().boxed().collect(Collectors.toSet());
Set<Integer> evens = "02468".chars().boxed().collect(Collectors.toSet());
Set<Integer> zero = "0".chars().boxed().collect(Collectors.toSet());
Then get an input from the user
Scanner scan = new Scanner(System.in);
System.out.println("Choose a number:");
String number = scan.next();
scan.close();
Parse number character by character to find out how many digits are matching each set:
long numberOfOdds = number.chars().filter(odds::contains).count();
long numberOfEvens = number.chars().filter(evens::contains).count();
long numberOfZeros = number.chars().filter(zero::contains).count();
Finally, display the result:
System.out.println("There are " + numberOfEvens + " even numbers, " + numberOfOdds + " odd numbers, and " + numberOfZeros + " zeros in ");
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
System.out.print("Please enter a digit: ");
int digit = in.nextInt();
boolean isAnInteger = false;
while (isAnInteger)
{
if (digit >= 10)
{
System.out.println("Please enter an integer: ");
}
else
{
System.out.println("Correct! " + digit + " is an integer!");
}
}
}
I'm currently taking AP Computer Science and I'm curious as to how to solve this (albeit basic) issue. I'm aware that "while" loops continue whatever is in their respective curly brackets when a condition in their parenthesis continues to be a met.
When I tried setting the while condition to while (digit >= 10), it resulted in an infinite loop (correct me, but it is due to the fact that if the user inputs a digit of 10 or greater, the condition will KEEP being met and continue infinitely). So, I tried setting the while condition to some boolean value, and an if nested inside with the prior condition. Now, when the user enters 10, nothing happens after, and the program ends.
How do I write the above code so that the System will continue printing "Please enter an integer:" if the condition (of inputting 10 or greater and the opposite) continues to be met?
There is a basic "poor design" issue that the variable isAnInteger has a scope wider than needed (it lives past the last line that needs it).
The "correct" approach is loop that contains the logic that determines "integerness" of the input and doesn't leave variables in scope when the loop ends, other than the captured input in digit of course.
Next, you want to separate the concerns of capturing input with checking it, so first create a method that gets a digit:
private static int readNumber(Scanner in) {
System.out.print("Please enter a digit: ");
int digit = in.nextInt();
in.nextLine(); // you must clear the newline char from the buffer
return digit;
}
Next, write a simple while() loop that keeps reading until it gets good input:
int digit = 10; // bad input
while (digit > 9) {
digit = readNumber(in);
}
Putting it all together with the final message:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int digit = 10; // initialize with "bad" input
while (digit > 9) {
digit = readNumber(in);
}
System.out.println("Correct! " + digit + " is an integer!");
}
private static int readNumber(Scanner in) {
System.out.print("Please enter a digit: ");
int digit = in.nextInt();
in.nextLine(); // you must clear the newline char from the buffer
return digit;
}
This approach makes the code much easier to read and understand.
Also notice how there is no repeated code (such as the line asking for a digit, or reading input).
The main conceptual piece here is that you don't update your value anywhere inside of your loop. Because it does not update, it will always remain the value it was when it entered the loop (that is, digit >= 10 will remain true until the program stops running).
You must update your values inside of your loop.
However, there's another concept you're missing: you're guaranteed to run the loop at least once, so you should take advantage of the do...while loop instead.
Note that I make use of nextLine() to avoid any wonky nextInt() issues.
(Oh, by the way: any number you're looking for is an integer. You should communicate that you're looking for an integer less than 10 instead.)
System.out.print("Please enter a digit: ");
int digit = Integer.parseInt(in.nextLine());
boolean isAnInteger;
do {
if (digit >= 10) {
System.out.println("Please enter an integer: ");
digit = Integer.parseInt(in.nextLine());
isAnInteger = false;
} else {
System.out.println("Correct! " + digit + " is an integer!");
isAnInteger = true;
}
} while (isAnInteger);
Yes, Makoto has it right.
You never update your values inside the while loop. In your original case, when you just wanted to keep printing out Please enter an integer: , you never ask for an input right after that line. Your original digit value will continue to be greater than or equal to 10, and will keep the loop going.
Even with your current code, you will still run into an infinite loop if your digit value is less than 10. Notice how the boolean isAnInteger is independent of whether your digit is less than 10.
The best way to fix this is by using something like this:
in = new Scanner(System.in);
System.out.print("Please enter a digit: ");
int digit = in.nextInt();
while (digit >= 10)
{
System.out.println("Please enter an integer: ");
digit = in.nextInt();
}
System.out.println("Correct! " + digit + " is an integer!");
What this does is it keeps checking to see if digit is greater than or equal to 10. If so, it will continue to ask the user for an input. If at any time during the iteration of the loop the user enters a value less than 10, it will not execute the next iteration, and leaves the loop. It will then execute the last println.
However, if the first input is less than 10, it will skip the while loop and execute the println at the bottom.
If you want to use a boolean like you did, you can do it in such a manner:
in = new Scanner(System.in);
System.out.print("Please enter a digit: ");
int digit = in.nextInt();
bool isAnInteger = true;
if (digit >= 10)
isAnInteger = false;
while (!isAnInteger) // checks if digit is not an integer
{
System.out.println("Please enter an integer: ");
digit = in.nextInt();
if !(digit >= 10)
isAnInteger = true;
}
System.out.println("Correct! " + digit + " is an integer!");
Makoto's way of using a do while loop is probably better, although this may be a better way of visualizing it (since you used a while loop).