For loop combining lines - java

I am trying to write a for loop that will allow a user to input five names and ages. The problem I am having is that it runs right the first time but then when it runs the second time the first name and last name are combined and it is not allowing two string entries. It will allow one then move to the integer entry for age. Any help is appreciated.
import java.util.Scanner;
public class QueueImp extends people{
public static void main(String[] args) {
String userL;
String userF;
int userA;
int userchoice = 0;
Scanner scnr = new Scanner(System.in);
for(int i = 0; i<5; i++) {
System.out.print("Please enter last name: ");
userL = scnr.nextLine();
System.out.println("");
System.out.println("Please enter first name: ");
userF = scnr.nextLine();
System.out.println("Please enter age: ");
userA = scnr.nextInt();
System.out.println("");
pName(userL, userF, userA);
}

The reason for that is the newline character (from inputting the integer) is not consumed yet. So, it is consumed by scnr.nextLine() of the next loop iteration, hence skipping the second last name input. To consume the newline character, add 1 more scnr.nextLine() right after scanning the integer.
for(int i = 0; i<5; i++) {
System.out.print("Please enter last name: ");
userL = scnr.nextLine();
System.out.println("");
System.out.println("Please enter first name: ");
userF = scnr.nextLine();
System.out.println("Please enter age: ");
userA = scnr.nextInt();
System.out.println("");
scnr.nextLine();
pName(userL, userF, userA);
}

Please use the next insted of nextLine
System.out.print("Please enter last name: ");
userL = scnr.next();
next() can read the input only till the space. It can't read two words separated by a space. Also, next() places the cursor in the same line after reading the input.
#Edit:
nextLine() reads input including space between the words (that is, it reads till the end of line \n). Once the input is read, nextLine() positions the cursor in the next line.
For reading the entire line you can use nextLine().
For reference: What's the difference between next() and nextLine() methods from Scanner class?
If you want to use the same than please use like this to consume the new line character by Integer.parseInt
userA = Integer.parseInt(scnr.nextInt());

Using scnr.next() will solve your problem.
Why it wasn't working with scnr.nextLine() is because next() will only return what comes before a space. nextLine() automatically moves the scanner down after returning the current line. The reason you were not able to enter the 2nd iteration of details is that the pointer already moved ahead before the 2nd iteration itself.
System.out.print("Please enter last name: ");
userL = scnr.next();
System.out.println("Please enter first name: ");
userF = scnr.next();
System.out.println("Please enter age: ");
userA = scnr.nextInt();
System.out.println(userL + " " + userF + " " + userA);

Related

Why does my while loop only work correctly for certain nested "if" statements but not others? [duplicate]

This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 1 year ago.
The while loop should ask the user which option they would like to select, and after the option is complete it should go back to the start of the while loop. Right now, it only works correctly for the second else if, and nothing else.
while(flag){
System.out.println("Select an option from the menu below:" +
"\n1: Display consecutive numbers in a right triangle" + //needs better explanation
"\n2: Determine if a number is divisible by 3" +
"\n3: Determine the number of periods and spaces in a string" +
"\n4: Display a right triangle of astrisks" +
"\n5: Exit"); //better explanation
String option = input.nextLine();
if(option.equals("1")){ //does not work
System.out.println("Enter number of columns: ");
int width = input.nextInt();
while(width<=0 || width%1!=0){
System.out.println("Invalid input! Please enter a positive width.");
width = input.nextInt();
}
numOfColumns(width);
}
else if(option.equals("2")){ //does not work
System.out.println("Enter number:");
int num = input.nextInt();
divisibleBy3(Math.abs(num));
}
else if(option.equals("3")){ //works
System.out.println("Enter string:");
String sentence = input.nextLine();
System.out.println("Number of periods and spaces: " + periodsAndSpaces(sentence) + "\n");
}
else if(option.equals("4")){ //does not work
System.out.println("Enter the width of the triangle:");
int length = input.nextInt();
rightTriangle(length, "");
}
else if(option.equals("5")){ //exits the while loop
flag = false;
}
else{
System.out.println("That is not a valid option!");
}
}
For the if/else if statements indicated above, the program will execute the given method, then display the menu, followed by "That is not a valid input!", and then the menu again, even if the user has not entered anything.
As mentioned in comments, you need to consume the rest of the line after you use input.nextInt(); or any other method that does not consume the entire line, because it only takes the input of part of the line and the rest remains on the scanner. You can fix this by input.nextLine(); to advance past the current line so that it is ready for the next input when the while loop restarts, like so:
//Get a partial line input eg "nextInt()"
int someInput = input.nextInt();
//Consume the rest of the line
input.nextLine();
//Now process the input
...
Here is a working solution using the above technique:
if(option.equals("1")){ //does not work
System.out.println("Enter number of columns: ");
int width = input.nextInt();
//Consume the rest of the line
input.nextLine();
//Now process the input
while(width<=0 || width%1!=0){
System.out.println("Invalid input! Please enter a positive width.");
width = input.nextInt();
}
numOfColumns(width);
}
else if(option.equals("2")){ //does not work
System.out.println("Enter number:");
int num = input.nextInt();
//Consume the rest of the line
input.nextLine();
//Now process the input
divisibleBy3(Math.abs(num));
}
else if(option.equals("3")){ //works
System.out.println("Enter string:");
String sentence = input.nextLine();
System.out.println("Number of periods and spaces: " + periodsAndSpaces(sentence) + "\n");
}
else if(option.equals("4")){ //does not work
System.out.println("Enter the width of the triangle:");
int length = input.nextInt();
//Consume the rest of the line
input.nextLine();
//Now process the input
rightTriangle(length, "");
}
else if(option.equals("5")){ //exits the while loop
flag = false;
}
else{
System.out.println("That is not a valid option!");
}
This allows each option to work correctly.
I deduce that your input variable is a Scanner object.
Option number 3 is the only one that works as expected because it is the only one that uses nextLine() for the option-specific input, clearing the newline at the end of the input from the input buffer.
If someone selects option 1, and then enters 3, this is what happens:
input contains the string "3\n"
nextInt() reads 3
input still has "\n" in it that hasn't been read yet
numOfColumns(3) runs
The next iteration of the loop starts
It outputs the menu
nextLine() reads from input, immediately finds the \n that's still there from step 3, clears that character, and returns an empty string
option's value of "" falls through to the invalid input case
The loop starts over again
It outputs the menu
nextLine() waits for new input content to be available again
To get the behavior you were expecting, call input.nextLine() after each input.nextInt() call.

Why is my for loop printing 2 of my prompts at one time while using (scanner).nextLine();

Is there a problem in my while or for loops by chance or am I missing something? First run through works fine but on the second I get this:
Enter course NAME: class name
Enter course HOURS: 4
Enter course GRADE: 4.0
You have entered class: jeff graves, class hours: 4 and, class grade 4.0
Do you want to continue:
y
Enter course NAME: Enter course HOURS:
It works just fine using (scanner).next(); but then I can only take one word from the user and it will throw an error from the nextInt when it rolls over.
public class GetGrades { //open class GetGrades
public static void main(String[] args) {
/**creating new instance of scanner named input to read user input*/
Scanner input = new Scanner(System.in); // create new instance of scanner object
boolean repeat = true; //boolean value for while loop holding array input
String s; // create string to store user input value for exiting loops
/** create 3 arrays to store course name, hours, and grades*/
String[] name = new String[20]; //type string array for class name
int[] hours = new int[20]; // type int array for class hours
float[] grade = new float[20]; //type float array for class grade
outerloop: // set break point for nested for loops exit on user input
while(repeat != false) {// while loop with boolean value to let user exit array input
for (int i=0; i<name.length; i++) { //for loop for name array
System.out.print("Enter course NAME: "); //prompt user for input
name[i] = input.nextLine(); //read next line value and store in array name
System.out.print("Enter course HOURS: "); //prompt user for input
hours[i] = input.nextInt(); //read the next int and store in array hours
System.out.print("Enter course GRADE: "); //prompt user for input
grade[i] = input.nextFloat(); //read the next float value and store in array grade
/**Print line to console summing um what the user has entered*/
System.out.println("You have entered class: " + name[i] + ", class hours: " + hours[i] +
" and, class grade " + grade[i]);
/**prompt user if wanted to enter more grades, break loop on n or N*/
System.out.println("Do you want to continue:");
s = input.next();
if ( s.equals("y") || s.equals("Y")) { //open if statement
repeat = true;
} else { //close if and open else
break outerloop;
} //close else statement
}//close for loop with i as count
}//close while
input.next() will read the next word. input.nextLine() will read up until the next time you press enter.
This means that when you write "y" and hit enter, you've input both a word "y", as well as the next enter, filling in both prompts at the same time and causing the next prompt to be written.
You can simply replace your next() with nextLine() when you ask to continue:
System.out.println("Do you want to continue:");
s = input.next();
becomes
System.out.println("Do you want to continue:");
s = input.nextLine();
thereby reading both the "y" and the enter. The next prompt is now free to accept new input.
When you input the grade, for example 12.3 and enter, "input.nextFloat();" will only take "12.3" but not "enter", so "enter" will be taken by the next scanner.
In my opinion,
first, change "s = input.next()" to "s = input.nextLine()", but it will take the "enter" of previous scanner "grade[i] = input.nextFloat();", so, second, put it into a while loop as a condition. like this
while((s = input.nextLine()).equals("")) {}
therefore, it won't stop til get the expect input.
try this..
System.out.print("Do you want to continue:");
while((s = input.nextLine()).equals("")) {}
if (s.equals("y") || s.equals("Y")) { // open if statement
repeat = true;
} else { // close if and open else
break outerloop;
} // close else statement

Begginner Java: nextLine Dilema

I've seen a couple of threads that are similar to this question, but had trouble finding the solution to my specific question.
The code I am writing is for a teacher to input a student's name and grades and receive an output of the final letter grade.
The area I am having trouble with is the last name input gets grouped together with the first name input, instead of asking the question by itself. How do I prompt these to appear as separate questions?
import java.util.*;
public class AssignmentTest {
public static void main (String [] args) {
Scanner console = new Scanner (System.in);
int iStudentID = 0; //StudentID
String sLastName = ""; //Last Name
String sFirstName = ""; //First Name
int iAssignmentsScore = 0; //Assignment Input
int iQuizzesScore = 0; //Quizzes Input
int iMidtermsScore = 0; //Midterm Input
int iFinalScore = 0;; //Final Input
//USER INPUT
//StudentID Input
System.out.println("Please enter the StudentID: ");
iStudentID = console.nextInt() ;
//Last Name Input
System.out.println ("Please enter the student's last name: ");
sLastName = console.nextLine() ;
//First Name Input
System.out.println ("Please enter the student's first name: ");
sFirstName = console.nextLine() ;
//Assignment Input
System.out.println ("Please enter the student's assignment score: ");
iAssignmentsScore = console.nextInt() ;
//Quiz Input
System.out.println ("Please enter the student's quiz score: ");
iQuizzesScore = console.nextInt ();
//Midterm Input
System.out.println ("Please enter the student's midterm score: ");
iMidtermsScore = console.nextInt ();
//Final Input
System.out.println ("Please enter the student's final score: ");
iFinalScore = console.nextInt ();
}
}
Since sFirstName and lFirstName , each consist of a word you should use
next()
Finds and returns the next complete token from this scanner.
Instead of
nextLine()
Advances this scanner past the current line and returns the input that
was skipped.
#madprogrammer has better explanation:
Actually, the issue is after iStudentID = console.nextInt() ; returns,
there is still a new line character in the buffer, so that when
sLastName = console.nextLine() ; is called, it skips of this
automatically (returning an empty String) - this is a very common
mistake
try this
System.out.println ("Please enter the student's last name: ");
sLastName = console.nextLine() ;
console.nextLine();
I think this may be as simple as adding another new line character \n. For example
System.out.println ("\nPlease enter the student's first name: ");
you should use next() instead of nextLine()

Arrays and input

My assignment asks me to write a program that will let the user input 10 players' name, age, position, and batting average. The program should then check and display statistics of only those players who are under 25 years old and have a batting average of .280 or better, then display them in order of age.
I've written my code for the input section (where it'll store them in an array):
static int players[] = new int [10];
static String name[] = new String [10];
static double average [] = new double [10];
static int age[] = new int [10];
static String position[] = new String [10];
//method to input names of Blue Jays
public static void inputInfo() throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
for(int i = 0; i < players.length; i++)
{
System.out.println("Enter player information.");
System.out.println("Input first and last name: ");
name [i] = br.readLine();
System.out.println("Input position: ");
position[i] = br.readLine();
System.out.println("Input batting average (e.g. .246): ");
String averageString = br.readLine();
average [i] = Double.parseDouble(averageString);
System.out.println("Input age: ");
age[i] = br.read();
System.out.println(" ");
}
}
My problem is the input. For the first player I input it shows me this (as it should):
Input first and last name:
John Smith
Input position:
pitcher
Input batting average (e.g. .246):
.300
Input age:
27
But my second input skips the name section completely and jumps to the position input. I can't really figure out why it's doing this! Can anyone help me out? Thanks in advance!
The read method reads only a single character of input; the rest of the line you've entered remains in the stream.
When the next loop starts, readLine detects that it can read the rest of the line already, so it does with no user input. It thinks the user input is already given.
For the input age, use readLine instead of read, and you can use Double.parseDouble to convert the resulting String input to a double.
When you read in the age here:
System.out.println("Input age: ");
age[i] = br.read();
the newline from the user pressing <Enter> is still there. So, when you go back and do
System.out.println("Enter player information.");
System.out.println("Input first and last name: ");
name [i] = br.readLine();
the newline is still in the buffer and will be read in here.
read() only reads a single character at a time. When you press after entering your age, it appends a new line character to the end which triggers the .readLine() for name.
System.out.println("Input age: ");
age[i] = Integer.parseInt(br.readLine());

Java Scanner not accepting input after the For loop

I am currently working on a program that requests input for the names and scores of two teams. When I request input for the name and 9 scores of the first team, the scanner accepts input just fine. However, after the for loop, the scanner does not accept input for the name of the second team. This is not the entire program, but I have included all the code up until the point where it is giving me trouble. I suspect that it may have something to do with the for loop because team2 accepts user input just fine when I place it before the for loop.
import java.util.Scanner;
public class sportsGame{
public static void main(String[] args){
Scanner input = new Scanner(System.in);
String team1;
String team2;
int team1Scores[] = new int[9]
int team1Total = 0;
int team2Scores[] = new int[9];
int team2Total = 0;
System.out.print("Pick a name for the first team: ");
team1 = input.nextLine();
System.out.print("Enter a score for each of the 9 innings for the "
+ team1 + " separated by spaces: ");
for(int i = 0; i < team1Scores.length; i++){
team1Scores[i] = input.nextInt();
team1Total += team1Scores[i];
}
System.out.print("Pick a name for the second team: ");
team2 = input.nextLine();
}
}
Scanner's nextInt method does not skip a line, only fetches the int. So when the first loop ends, there is still one newline character left and your input.nextLine() returns a blank string. add a input.nextLine() after your loop to skip this blank line and to solve your problem like this:
for(int i = 0; i < team1Scores.length; i++){
team1Scores[i] = input.nextInt();
team1Total += team1Scores[i];
}
input.nextLine();
//rest of your code

Categories