Why is first for loop iteration skipped? - java

my code is yielding an unexpected result. It seems my for loop skips the first iteration and I don't understand why.
public static void main(String[] args) {
Scanner get = new Scanner(System.in);
int number;
// Ex.1.
String family_name;
String[] family_array;
System.out.println("Enter number of family members: ");
number = get.nextInt();
family_array = new String[number];
for(int i = 0; i < number; i++){
System.out.println("Enter family member name: ");
family_name = get.nextLine();
family_array[i] = family_name;
}
for(int i = 0; i < number; i++){
System.out.println(family_array[i]);
}
}
Returns... (pretend the number input are names)
Enter number of family members:
5
Enter family member name:
Enter family member name:
1
Enter family member name:
2
Enter family member name:
3
Enter family member name:
4
1
2
3
4
Why is the first get.nextLine() skipped?

Currently your call to Scanner#nextInt is not consuming the newline character so it is being passed through to your first call of Scanner#nextLine, therefore it does not block.
You will need to add
get.nextLine();
after calling nextInt so that your first call to nextLine will block for IO.

Notice that blank line between 4 and 1?
4
//this is it
1
When you call get.NextInt() you'd not eating the whole line, just the next int. The empty rest of the line is eaten in your first loop iteration. Add a call to get.nextLine() after reading the int.

What worked for me was instantiating a new Scanner in each iteration:
for(int i = 0; i < number; i++)
{
System.out.println("Enter family member name: ");
Scanner loopGet = new Scanner(System.in);
family_name = loopGet.nextLine();
family_array[i] = family_name;
}

I am going to say it is because you still have a buffered CR/LF - so the first one is set to blank. Notice the blank line as you print your family names (numbers). That is your blank family name.
The keyboard input is a buffered stream - it has your 5, and it has a CR/LF (or perhaps just a LF, depending on your OS).
You probably want to get the LINE and then do a string.convert, atoi, system.convert (whichever one is for Java) to get the #.

number = get.nextInt();
// if i enter 4 then it will 4\n and nextInt will take only 4
// and the \n will be taken as input by the getline.
get.nextLine();
//this will return the "" from ""\n . so adding this will solve your problem
family_array = new String[number];

Related

How to output a long string from Scanner input in Java [duplicate]

This question already has answers here:
What's the difference between next() and nextLine() methods from Scanner class?
(16 answers)
Closed 2 years ago.
class Property {
public static void main (String[] args) {
Scanner input = new Scanner(System.in);
String[] rooms = new String[15];
System.out.println("How many rooms? ");
int roomLimit = input.nextInt();
for (int i = 0; i < roomLimit; i++) {
System.out.println("Enter room name " + (i + 1));
rooms[i] = input.next();
}
When I enter room names that are single words like, 'double, single, master, etc.', the list of room names displays fine. But when I enter room names with more than one word, only the first word is listed, and the second word of the first room name automatically becomes the second room name as shown below.
How many rooms?
4
Enter room 1
Double Duluxe
Enter room 2
Enter room 3
Couple Golden
Enter room 4
List of Chosen Rooms
Room 1: Double
Room 2: Duluxe
Room 3: Couple
Room 4: Golden
Process finished with exit code 0
Just use the method Scanner.nextLine() instead of using Scanner.next().
Scanner.next() , according to the docs:
Finds and returns the next complete token from this scanner.
This means that it will only read the first word (the token, in your case). Scanner.nextLine(), on the other hand (docs):
(...) returns the rest of the current line, excluding any line
separator at the end.
Which means it will read the entire line.
Your code will look like this after the change:
// ...
System.out.println("Enter room name " + (i + 1));
rooms[i] = input.nextLine();
// ...

For loop skipping index 0 when user's input and print in Java

For example, I entered a size of 3 Students. It skips index 0 in the console also in printing.
Please refer to this image, I have a sample size of 3 students and its output.
I don't have the slightest idea of why it skips index 0? Thanks for the help!
import java.util.Arrays;
import java.util.Scanner;
class string{
public static void main(String [] args){
Scanner console = new Scanner(System.in);
System.out.print("Enter Student Size: ");
int studentSize = console.nextInt();
String [] arrName = new String[studentSize];
for (int i=0; i<arrName.length; i++){
System.out.print("Enter student name: ");
String nameString = console.nextLine();
arrName[i] = nameString;
}
System.out.print(Arrays.toString(arrName));
//Closing Braces for Class and Main
}
}
The problem is with the console.nextInt(), this function only reads the int value.So In your code inside the loop console.nextLine() first time skip the getting input.just puting console.nextLine()afterconsole.nextInt()
you can solve the problem.
public static void main(String [] args){
Scanner console = new Scanner(System.in);
System.out.print("Enter Student Size: ");
int studentSize = console.nextInt();
console.nextLine();
String [] arrName = new String[studentSize];
for (int i=0; i<arrName.length; i++){
System.out.print("Enter student name: ");
String nameString = console.nextLine();
arrName[i] = nameString;
}
System.out.print(Arrays.toString(arrName));
//Closing Braces for Class and Main
}
The reason for this skip is due to the different behavior of the console.nextInt() and console.nextLine() as:
console.nextInt() reads the integer value entered, regardless of whether you hit the enter for new-line or not.
console.nextLine() reads the whole line, but as you previously hit thee enter when you give the size of Array.
3 was accepted as the size of the Array and when you hit enter it was accepted as the first value for you array which is a blank space or I can say it is referred as "".
Following are the two resolution for this:
Either put a console.nextLine() call after each console.nextInt() to consume rest of that line including newline
Or, even better, read the input through Scanner.nextLine and convert your input to the proper format you need. you may convert to an integer using int studentSize = Integer.parseInt(console.nextLine()) method. (Surround it with try-catch)

Why is my message printing twice when I break out of the inner if?

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.

"for" loop does not iterate the way I want [duplicate]

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());

Java - Skipping a line when reading user input into an array (for loop)

Here's my code - The objective is to enter some basic info (age, name, gender) for x number of patients.
public static void main(String[] args) {
int numPatients = 2;
int[] age = new int[numPatients];
String[] gender = new String[numPatients];
String[] name = new String[numPatients];
Scanner in = new Scanner(System.in);
/*
* Obtaining patients details: name, gender, age
* First create a Scanner input variable to read the data
*/
for (int i = 0; i < numPatients; i++)
{
System.out.println("Enter name of patient " + (i+1));
name[i] = in.nextLine();
System.out.println("Enter gender (male/female) of patient " + (i+1));
gender[i] = in.nextLine();
System.out.println("Enter age of patient " + (i+1));
age[i] = in.nextInt();
}
The issue I'm having is when the loop goes to the 2nd variable, i.e. I'm not able to enter a value for the name of the patient. It seems to skip taking the input there and goes directly to the next input, which is gender.
Enter name of patient 1
Mark
Enter gender (male/female) of patient 1
Male
Enter age of patient 1
34
Enter name of patient 2 //Skipped. Could not enter input here
Enter gender (male/female) of patient 2
Jenna
Any idea why that happens? Is it better to use BufferedReader instead?
If you must use Scanner, then always use nextLine(). The problem is that nextInt() reads only the integer part of the input and stops before it reads the Enter keypress. Then the next call to nextLine() sees the Enter keypress in the buffer and things you entered an empty name.
So you can do something like:
age[i] = Integer.parseInt(in.nextLine());
and be prepared to handle the exception that will happen if the user types something other than a number.
If you are assured that name will be a single word (not an issue for male or female)then you can modify the scanner input to just get the string;
in.next();
this works fine (only if name's a single word ).

Categories

Resources