This question already exists:
Scanner issue when using nextLine after nextXXX [duplicate]
Closed 9 years ago.
I am trying to get the name and jersey number of 3 hockey players from the user. I then make an object from my created class called HockeyPlayer with the data I have. I then put it into the array. The second iteration does not work. Please help! Thank you in advance.
ArrayList<HockeyPlayer> array = new ArrayList<HockeyPlayer>();
//For loop to input names
for(int i=0; i < 3; i++)
{
System.out.print("Enter name of Player " + i +":");
startName = keyboard.nextLine();
System.out.print("Enter jersey number of Player " + i +":");
playNum = keyboard.nextInt();
//Make objects and add to array
HockeyPlayer p = new HockeyPlayer(startName, playNum);
array.add(p);
}
keyboard.close();
The problem here is that in every iteration of your loop, you make a call to nextLine(), then a call to nextInt(), but after you make the call to nextInt(), the newline character has not been read. Basically, if the input is something like
First Player Name
1
Second Player Name
2
then, after the first iteration of your loop, the Scanner has just finished reading in the 1, but not the newline right after it. Hence, in the second iteration, the nextLine() deals with the newline after 1, but only that newline. Then, the nextInt() call will try to turn Second into an int, and throws the InputMismatchException.
Common ways of going around it are to either put another nextLine() call right after the call to nextInt() (and just throw away this extra newline), or to just read in the line with the number all at once with a call to nextLine(), and parse out the int using Integer.parseInt().
From InputMismatchException's JavaDoc:
Thrown by a Scanner to indicate that the token retrieved does not match the pattern for the expected type, or that the token is out of range for the expected type.
It seems that you entered a string whereas nextInt() expects an integer.
If by second iteration you mean the second for, you probably have to override your HockeyPlayer.toString() method.
public String toString() {
return name+" "+startNum;
}
I assume your keyboard variable is of type java.util.Scanner. If that is true then you need to call keybord.reset() at the end of loop.
Your problem is that keyboard.nextInt() does not consumes end of line which is produced when you hit enter. This end of line character is responsible for your exceptions.
This code works:
HockeyPlayer [] hArr = new HockeyPlayer[3];
for(int i=0; i < 3; i++)
{
String startName = "";
Scanner scanner = new Scanner(System.in);
int playNum = 0;
System.out.print("Enter name of Player " + i +":");
startName = scanner.nextLine();
System.out.print("Enter jersey number of Player " + i +":");
playNum = scanner.nextInt();
scanner.reset();
HockeyPlayer p = new HockeyPlayer(startName, playNum);
hArr[i] = p;
}
It is good to go with:
int playNum = Integer.parseInt(sc.nextLine());
Related
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 6 years ago.
Why when the first time process go into the loop, it doesn't stop and wait for user input string first, instead will print out the space and enter? It will only stop on the second time of loop and wait for the user to input something.
It's hacker rank 30 Days of code > Day 6 problem by the way.
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner stdin = new Scanner(System.in);
int input;
input = stdin.nextInt();
while( input-- >= 0 ){
String sentence = stdin.nextLine();
char[] CharArray = sentence.toCharArray();
for( int i=0; i < sentence.length() ; i=i+2 ){
System.out.print(CharArray[i]);
}
System.out.print(" ");
for( int i=1; i < sentence.length() ; i=i+2 ){
System.out.print(CharArray[i]);
}
System.out.println();
}
stdin.close();
}
When you enter a number, you also press the ENTER key to enter your input. So the following line consumes the number, but it does not consume the carriage return:
input = stdin.nextInt();
Instead, that carriage return is consumed in the first iteration of the loop by this line:
String sentence = stdin.nextLine();
In other words, it appears from your point of view that the first iteration of the loop did not prompt you for any input, because you unknowingly already entered it. If you want to avoid this, you can add an explicit call to Scanner.nextLine():
input = stdin.nextInt();
stdin.nextLine();
When you enter a number and press enter, nextInt() reads the integer you entered but the '\n' character is still in the buffer, so you need to empty it before entering the loop, so you can simply write : stdin.nextLine() before entering the loop
On first time, you are scanning twice.
input = stdin.nextInt();
it will wait for your input.once you give value it will move ahead. then again
String sentence = stdin.nextLine();
it will take enter(or carriage return) and print that with space.
after this it will work properly
Solution :
use stdin.nextLine(); just after input = stdin.nextInt();
You need to add one more -
stdin.nextLine();
after
input = stdin.nextInt();
without collecting it in some variable. This will consume the newline character appeared just after you finished inputting your integer in below line -
input = stdin.nextInt();
I am having a little problem with my code. Compiling and running works well, however, when I attempt to break out of the inner loop,
System.out.println("Type which category you want to add to.");
System.out.println("Homework, Classwork, Labs, Test, Quizzes, Midterm, Final");
The code above is printing twice to the terminal when I only want it to print once.
I have a feeling that is a simple mistake with the way my brackets are aligned but I am having difficulty with figuring out how to do it. Any help would be greatly appreciated!
import java.util.Scanner;
public class GetGrade {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
final int MAX = 15;
int[] homework = new int[MAX];
int[] classwork = new int[MAX];
int[] lab = new int[MAX];
int[] test = new int[MAX];
int[] quizzes = new int[MAX];
int[] midterm = new int[MAX];
int[] fin = new int[MAX];
int hwCount, clCount, labCount, testCount, quizCount, midCount, finCount;
double hwTotal, clTotal, labTotal, testTotal, quizTotal, midTotal, finTotal;
double grade = 0;
String selection = "";
System.out.println();
System.out.println("Welcome to GetGrade!");
System.out.println();
while (true) {
System.out.println("Type which category you want to add to.");
System.out.println("Homework, Classwork, Labs, Test, Quizzes, Midterm, Final");
selection = input.nextLine();
if (selection.equals("homework")) {
System.out.print("What percentange of your grade is homework? > ");
double hwPercent = input.nextDouble();
System.out.println("Now begin typing your grades. When you are finished, type -1.");
for (int i = 0; i < homework.length; i++) {
homework[i] = input.nextInt();
hwTotal = homework[i] * hwPercent;
grade += hwTotal;
if (homework[i] == -1) break;
}
}
}
}
}
It's just as trivial as it seems:
The call to input.nextInt(); in your inner loop does not include the newline.
So you are breaking of the innerloop, receiving the next line which only contains the newline - character in input.nextLine(); which is the remaining input of your "-1\n" line and proceed with the main loop again as it does not match "homework".
Try setting the conditional variable in your while loop to an actual boolean rather than true.
Also, when you invoke "break", you are only breaking out of the for loop. If you reassign a boolean variable to false at this point, you would exit the while loop completely.
Just before while loop ends, add a "Do you want to continue? (Y/N)" functionality.
If user enters "N" or anything else, execute another break. And that break will make you get out of the while loop.
The simple way to get your code working is to change
selection = input.nextLine();
to
selection = input.next();
next() only reads in a string value (which is what you are actually doing in your code) instead of the newline character as Peter has suggested.
So the an extra iteration of the while does not take place when you read the newline character.
When you use a scanner to read a line from the keyboard, it reads everything up to and including the newline character the user types to submit their input. So for example:
Type which category you want to add to.
Homework, Classwork, Labs, Test, Quizzes, Midterm, Final
>
If you type "homework" and then ENTER, the actual input becomes "homework\n". input.nextLine() will scan the input until it encounters the first newline character, '\n', which it will consume and then it returns everything up to that point (i.e. "homework").
Your problem here is that input.nextInt() does NOT consume a newline character, and so there is still a newline character in the input buffer by the time your while loop starts another round.
Now begin typing your grades. When you are finished, type -1.
> ...
> -1
=> User input is "-1\n"
-------------------------------
// Meanwhile, back in the code...
for (int i=0;i<homework.length;i++) {
homework[i] = input.nextInt(); // <--- This call consumes "-1" but leaves '\n'
hwTotal = homework[i] * hwPercent;
grade += hwTotal;
if (homework[i] == -1) break;
}
That newline is consumed by the next call to input.nextLine(), leaving the input buffer empty.
while (true) {
System.out.println("Type which category you want to add to.");
System.out.println("Homework, Classwork, Labs, Test, Quizzes, Midterm, Final");
selection = input.nextLine(); // <--- This call consumes the leftover '\n' and returns the empty string
...
And because "" is not equal to "homework", the while loop goes around one more time, but this time the input buffer is empty, and so the call to input.nextLine() behaves as you would expect.
// selection is empty, so this condition fails and the program loops back around
if (selection.equals("homework")) {
...
There are two easy solutions to this problem. You can
Use Integer.parseInt(input.nextLine()) instead of input.nextInt()
Add an extra call to input.nextLine() at the end of your while loop to consume the final newline character
The first option is probably the most robust, and you get the added benefit of a run-time error being thrown if they do not give you a valid integer as input.
The first print statement in my for loop is printed twice before moving on to the next line. But then it runs through the loop like it should after that?
I tried using my debugger, but I've never used it before, we haven't gone over using it in any of my classes and I wasn't too sure what I was doing
public static void main(String[] args)
{
int numElements;
Scanner keyboard = new Scanner(System.in);
System.out.println("How many people are you adding: ");
numElements = keyboard.nextInt();
ArrayBndQueue queue = new ArrayBndQueue<>(numElements + 1);
for(int index =0; index <= numElements; index++)
{
System.out.println("Enter a gender and name (ex: f jenny)");
String name = keyboard.nextLine();
System.out.println(name);
queue.enqueue(name);
}
}
You have what's called an off-by-one error. One of the fundamentals of many languages is that they are zero-based when it comes to indexing. You have got that half-right, you have one bug (actually two), and instead of fixing that bug, you have only fixed the symptom....
Off by one bug
The bug is in your for-loop:
for(int index =0; index <= numElements; index++)
Where you are looping one time too many... you should use < instead of <= in the test condition. That way you will loop numElements times.
Instead of fixing that, you made the queue 1-element too large, so you should change:
ArrayBndQueue queue = new ArrayBndQueue<>(numElements + 1);
to be:
ArrayBndQueue queue = new ArrayBndQueue<>(numElements);
That should sort out the extra loop, and you will still have space for the values.
Scanner management bug
Scanner.nextInt() only pulls the int value off the scanner, not the terminating newline/carriage-return, so when you call nextLine() in your loop it clears the already-in-the-scanner line, instead of waiting for input.
You need to clear the line from the scanner before advancing after the nextInt() call:
numElements = keyboard.nextInt();
keyboard.nextLine();
That should clear your scanner for the next input.
From the documentation:
nextInt() - Scans the next token of the input as an int. This method will throw InputMismatchException if the next token cannot be translated into a valid int value as described below. If the translation is successful, the scanner advances past the input that matched.
"advances past the input that matched" means before the newline/carriage-return.
Best fix is to simply remove the elementType from the scanner method. By doing this, you prevent the first instance of your loop from clearing out the input as rolfl mentions above. Revised code as follows:
for(int index =0; index <= numElements; index++)
{
System.out.println("Enter a gender and name (ex: f jenny)");
//removed "Line" from ".nextLine" to prevent clearing below
String name = keyboard.next();
System.out.println(name);
queue.enqueue(name);
}
This question already has answers here:
Java calculator not executing if-statement [duplicate]
(3 answers)
Closed 9 years ago.
In the code below, in the first iteration of the first for loop, boxes[a] is automatically assigned a null value.
The remainder of the iterations are fine (user input is accepted). Only the first has the issue where a null value is automatically assigned.
Does anyone know why this may be? Thank you.
package testing;
import java.util.Scanner;
public class Testing {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Scanner in2 = new Scanner(System.in);
int boxNumber;
boxNumber = in.nextInt();
String[] boxes = new String[boxNumber];
System.out.println(boxNumber);
for(int a=0; a <= boxes.length - 1; a++){
boxes[a] = in.nextLine();
System.out.println(boxes[a]);
}
int packageNumber;
packageNumber = in2.nextInt();
String[] packages = new String[packageNumber];
System.out.println(packageNumber);
for(int n=0; n <= packageNumber - 1; n++){
packages[n] = in.nextLine();
System.out.println(packages[n]);
}
}
}
The scenario fitting the description of what occurs is when you type in a number on the first line, then the rest of the lines are strings for the boxes.
But the nextInt() method doesn't advance past the first newline character, so the first time you call nextLine(), it matches on the rest of the line until the first newline character, "" ( not null).
After the call to nextInt(), insert a call to newLine() before the for loop to bypass the first newline character.
String firstNewLine = in.nextLine();
for(int a=0; a <= boxes.length - 1; a++){
when you did hit enter after entring the first number you also have and empty line that's why nextLine() return empty string, you can use this boxNumber = in2.nextInt(); instead but I would suggest to think of another way, normally you don't need two Scanner instances
I am trying to assign each string a user inputs to a String array. The entire thing is in a for loop and is evaluated by the index of the array. My code is:
String skillAssign[] = new String[100];
for (int i=0; isDone == false; i++)
{
System.out.println(skillAssign[i]);
System.out.println(i);
skillAssign[i] = keyboard.nextLine();
if ((!(skillAssign[i].equalsIgnoreCase("stats"))) && (!(skillAssign[i].equalsIgnoreCase("done"))))
{
assignmentValue = keyboard.nextInt();
if (((skillAssign[i].equalsIgnoreCase("health"))) && (skillPoints - assignmentValue >=0))
{
System.out.println("Added " + assignmentValue + " points to Health!");
skillPoints = (skillPoints - assignmentValue);
newMaxHealth = (assignmentValue + newMaxHealth);
}
//code that evaluates the string located inside the skillAssign[i] for other stats
}
The first string evaluates properly, but when I go to input the second string, I get java.util.InputMisMatchException. How can I get it so it assigns a string to each index of the array inputted by the user, then evaluate it? (I think I got the evaluation part though)
I tried to limit the post to relevant code, so things like isDone are omitted, but isDone is changed to true when done is typed and keyboard is constructed with Scanner keyboard = new Scanner all other variables are set to 0 except for skillPoints
I have tested the abovementioned code, and this is what happens:
We enter the loop.
You are requested to input the first string (through keyboard.nextLine()). I inputted 'health'.
You are requested to input an integer (through keyboard.nextInt()). I inputted '40'.
We re-enter the loop.
You are requested to input an integer (through keyboard.nextInt()).
...
It seems that I'm not asked to input the second string, but instantly the integer.
I do not know why it is, but it looks like nextInt() causes the next nextLine() to be skipped.
Maybe you can replace
assignmentValue = keyboard.nextInt();
with
try {
assignmentValue = Integer.parseInt(keyboard.nextLine());
}
catch (NumberFormatException exc) {
throw new InputMismatchException(exc.getMessage());
}
EDIT
I saw a post on StackOverflow which briefly mentions why nextLine() after nextInt() is skipped.
i believe this is closer to your intention. this way the reference to your keyboard input that nextLine grabs isn't lost on each iteration, but remains preserved in a new String instance. correct?
System.out.println(i);
String getMe = keyboard.nextLine();
skillAssign[i] = new String(getMe);
System.out.println(skillAssign[i]);