I am having trouble coding a hw program that is made to generate test with multiple choice and essay questions. Everything works except my program skips lines when it goes to read a part of the essay class. I know it has to do with the scanner and scan.nextline, scan.nextInt and scan.next, etc but I am confused on how exactly to fix it.
Thank you for your help.
import java.util.*;
public class TestWriter
{
public static void main (String [] args)
{
Scanner scan = new Scanner (System.in);
String type=null;
System.out.println ("How many questions are on your test?");
int num = scan.nextInt ();
Question [] test = new Question [num];
for (int i=0; i <num; i++)
{
System.out.println ("Question " + (i+1) + ": Essay or multiple choice question? (e/m)");
type = scan.next ();
scan.nextLine ();
if (type.equals ("e"))
{
test [i] = new Essay ();
test [i].readQuestion ();
}
if (type.equals ("m"))
{
test [i] = new MultChoice ();
test [i].readQuestion ();
}
}
for (int i=0; i <num; i++)
{
System.out.println ("Question " + (i+1)+": "+ type);
test [i].print ();
}
}
}
here is the essay class
public class Essay extends Question
{
String question;
int line;
public void readQuestion ()
{
System.out.println ("How many lines?");
line = scan.nextInt ();
scan.next ();
System.out.println ("Enter the question");
question = scan.nextLine ();
}
public void print ()
{
System.out.println (question);
for (int i=0; i <line; i++)
System.out.println ("");
}
}
Using scan.nextInt() will generate the following problems
If your input is "5 5", nextInt() will get the next integer leaving the remaining " 5" of the buffer line. Of which the remaining " 5" will be caught by
type = scan.next();
In the class test writer:
System.out.println("How many questions are on your test?");
int num = scan.nextInt();
Question[] test = new Question[num]; for(int i=0; i<num; i++)
{
System.out.println("Question " + (i+1) + ": Essay or multiple choice question? (e/m)");
type = scan.next();
This will generate the issue as i have mentioned above.
To fix this you can either
a) Ensure that input is solely a number
b) Get the entire line like so String temp = scan.nextLine(); then convert it to a integer. This will you can play with the string and check if its the input you require i.e if the 1st letter / set of numerical digits is an e/m or an integer.
The problem with scan.nextInt() is that it only gets the next integer of the input line. If there are spaces after the input it was taken from i.e "5 5" it will grab only the next int 5 and leave " 5" behind.
Thus i would recommend using scan.nextLine() and manipulating the string to ensure that the input can be handled and verified and at the same time ensuring that you do not get confused of where the scanner is at.
You should use .next() / .nextInt() if you are handling an input with various parameters you want to specifically catch such as "25 Male Student 1234" in this case the code would be as such
int age = scan.nextInt();
String sex = scan.next();
String job = scan.next();
int score = scan.nextInt();
Your readQuestion function should be ...
public void readQuestion()
{
System.out.println("How many lines?");
line = scan.nextInt();
scan.nextLine();
System.out.println("Enter the question");
question = scan.nextLine();
}
It should be scan.nextLine(); to add an empty new line at the end
In your TestWriter.main() method what are you expecting at 3 line in following code:
System.out.println("Question " + (i+1) + ": Essay or multiple choice question? (e/m)");
type = scan.next();
scan.nextLine(); //LINE 3: What are you expecting user to enter over here.
the control flow will stuck at this point unless you enter something on the console.
Related
This question already has answers here:
Scanner is skipping nextLine() after using next() or nextFoo()?
(24 answers)
Closed 3 years ago.
The question is that write a class named Seyyed includes a method named seyyed. I should save the name of some people in a String array in main method and calculate how many names begin with "Seyyed". I wrote the following code. But the output is unexpected. The problem is at line 10 where the sentence "Enter a name : " is printed two times at the first time.
import java.util.Scanner;
public class Seyyed {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter the number of names :");
int n = in.nextInt();
String[] names = new String[n];
for (int i = 0; i < names.length; i++) {
System.out.println("Enter a name : ");
names[i] = in.nextLine();
}
int s = seyyed(names);
System.out.println("There are " + s + " Seyyed");
in.close();
}
static int seyyed(String[] x) {
int i = 0;
for (String s : x)
if (s.startsWith("Seyyed"))
i++;
return i;
}
}
for example When I enter 3 to add 3 names the program 2 times repeats the sentence "Enter a name : " and the output is something like this:
Enter the number of names :3
Enter a name :
Enter a name :
Seyyed Saber
Enter a name :
Ahmad Ali
There are 1 Seyyed
I can enter 2 names while I expect to enter 3 names.
The problem occurs as you hit the enter key, which is a newline \n character. nextInt() consumes only the integer, but it skips the newline \n. To get around this problem, you may need to add an additional input.nextLine() after you read the int, which can consume the \n.
Right after in.nextInt(); just add in.nextLine(); to consume the extra \n from your input. This should work.
Original answer: https://stackoverflow.com/a/14452649/7621786
When you enter the number, you also press the Enter key, which does an "\n" input value, which is captured by your first nextLine() method.
To prevent that, you should insert an nextLine() in your code to consume the "\n" character after you read the int value.
Scanner in = new Scanner(System.in);
System.out.print("Enter the number of names :");
int n = in.nextInt();
in.nextLine();
String[] names = new String[n];
Good answer for the same issue: https://stackoverflow.com/a/7056782/4983264
nextInt() will consume all the characters of the integer but will not touch the end of line character. So when you say nextLine() for the first time in the loop it will read the eol left from the previous scanInt(), so basically reading an empty string. To fix that use a nextLine() before the loop to clear the scanner or use a different scanner for Strings and int.
Try this one:
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Enter the number of names :");
int n = in.nextInt();
in.nextLine();
String[] names = new String[n];
for (int i = 0; i < names.length; i++) {
System.out.println("Enter a name : ");
names[i] = in.nextLine();
}
int s = seyyed(names);
System.out.println("There are " + s + " Seyyed");
in.close();
}
static int seyyed(String[] x) {
int i = 0;
for (String s : x)
if (s.startsWith("Seyyed"))
i++;
return i;
}
So I have a program that takes orders for vehicle purchases (meant to learn the basics of java. Right now this iteration of the assignment is focusing on inheritance). Hierarchy: Orders.java (Main program), Vehicle.java (parent class), Boat.java/Car.java/Truck.java(child classes).
I was showing my menus manually in the main program before but tried to delegate that responsibility to my Vehicle class so it would be more generic and each child could pass in a Question Prompt and Array of Choices to the showMenu function. So nothing was being done manually anymore.
Here's what happened when it was done manually (worked fine):
System.out.println("What type of Car is this?");
System.out.println("\t1. Sedan");
System.out.println("\t2. Coupe");
System.out.println("\t3. Wagon");
System.out.print("Choice: ");
while (!sc.hasNext("[123]")) {
System.out.println("");
System.out.println("");
System.out.println("That's not an option! Please try again.");
System.out.println("What type of Car is this?");
System.out.println("\t1. Sedan");
System.out.println("\t2. Coupe");
System.out.println("\t3. Wagon");
System.out.print("Choice: ");
sc.next();
}
choice = sc.next();
if(choice.equals("1")){
car.setCarType("Sedan");
} else if (choice.equals("2")){
car.setCarType("Coupe");
} else if (choice.equals("3")){
car.setCarType("Wagon");
} else{
car.setCarType("unknown");
}
Here's how it works now (crashes before stopping to let the user give input):
public int showMenu(String prompt, String[] choices){
Scanner sc = new Scanner(System.in);
System.out.println(prompt);
String choiceIdentifiers = "";
int choice;
for(int i = 0; i < choices.length; i++){
Integer j = i+1;
System.out.println("\t\t" + j + ". " + choices[i]);
choiceIdentifiers = choiceIdentifiers + j.toString();
}
System.out.print("Choice: ");
while (!sc.hasNext("[" + choiceIdentifiers +"]")) {
System.out.println("");
System.out.println("");
System.out.println("That's not an option! Please try again.");
System.out.println(prompt);
for(int i = 0; i < choices.length; i++){
System.out.println("\t\t" + (i+1) + ". " + choices[i]);
}
System.out.print("Choice: ");
sc.next();
}
choice = Integer.parseInt(sc.next());
sc.close();
return choice - 1;
}
Also here's a link to my github repo with the full program.
What could be happening in the showMenu function to crash the program and throw the NoSuchElementException?
Any help would be greatly appreciated.
The problem is that you're closing the System.in stream when you call sc.close().
When you construct a new Scanner that uses the closed System.in stream and you call next() on it, you'll get this error.
To solve the problem, don't close the System.in (don't call close() on any Scanner that uses this stream) until you're done processing user input.
Here is a MCVE:
public class Example {
public static void main(String[] args) {
Scanner sc1 = new Scanner(System.in);
sc1.close();
Scanner sc2 = new Scanner(System.in);
sc2.next();
}
}
The problem is in Vechile.java show menu method
Scanner sc = new Scanner(System.in);
System.out.println(prompt);
String choiceIdentifiers = "";
int choice;
for(int i = 0; i < choices.length; i++){
Integer j = i+1;
System.out.println("\t\t" + j + ". " + choices[i]);
choiceIdentifiers = choiceIdentifiers + j.toString();
}
so here after iterating on choices array you are concatinating choiceIdentifiers string that will become 12 after loop but you are expecting input from user as 1 or 2 for model type of vechile so if you will put 1 for model then
!sc.hasNext("[" + choiceIdentifiers +"]")
is not having 1 so it will throw no such element error , hope this will help you
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
I have created the basic structure to the program, but I cant seem to exit the loop no matter what I try.
Also I want it to display the information that the user will input; from the keyboard, on to the console once I have exited the loop, but I am not sure as to how to do that.
import java.util.Scanner;
public class Requirement1 {
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
String name, game, time, points;
int i = 0;
System.out.println("Please Enter Your Name");
name = scan.nextLine();
System.out.println("Players Name: " + name);
while (i < 100)
{
Scanner scan2 = new Scanner(System.in);
System.out.println("Please Enter a Game Name (If You Are Done type \"quit\")");
game = scan.nextLine();
System.out.println("Game: " + game);
Scanner scan3 = new Scanner (System.in);
System.out.println("Please Enter Your Score");
points = scan.nextLine();
System.out.println("Your Score: " + points);
Scanner scan4= new Scanner (System.in);
System.out.println("Please Enter the amount of time Spent Playing in Minutes");
time = scan.nextLine();
System.out.println("Time played: " + time);
}
}
Include an i++ inside of the loop.
In order to break out of the while loop, you need to either make i < 100 false, or add an explicit statement to stop the loop (break, return, throw or System.exit, depending upon your requirements).
If you want to break the loop when the user enters "quit" and execute the code following the loop:
System.out.println("Please Enter a Game Name (If You Are Done type \"quit\")");
game = scan.nextLine();
if (game.equals("quit")) {
break;
}
At present, i is never changed from 0, so i < 100 is always true. Also, it is not read otherwise. Unless you need it for some other purpose, you can remove i and change the while loop declaration to:
while (true) {
// ...
}
This condition obviously can never be false, so you would need an explicit break in the loop.
In general, I like to use a for loop when I know the exact number of times the loop will run. If I don't know how many times the loop will run, then I like to use a while loop.
A for loop:
import java.util.Scanner;
public class Requirement1 {
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
String name, game, time, points;
System.out.println("Please Enter Your Name");
name = scan.nextLine();
System.out.println("Players Name: " + name);
for (int i = 0; i < 100; i++) {
Scanner scan2 = new Scanner(System.in);
System.out.println("Please Enter a Game Name (If You Are Done type \"quit\")");
game = scan.nextLine();
if (game.equals("quit")) {
break;
}
System.out.println("Game: " + game);
Scanner scan3 = new Scanner (System.in);
System.out.println("Please Enter Your Score");
points = scan.nextLine();
System.out.println("Your Score: " + points);
Scanner scan4= new Scanner (System.in);
System.out.println("Please Enter the amount of time Spent Playing in Minutes");
time = scan.nextLine();
System.out.println("Time played: " + time);
}
}
A while loop:
import java.util.Scanner;
public class Requirement1 {
public static void main(String[] args) {
Scanner scan = new Scanner (System.in);
String name, game, time, points;
System.out.println("Please Enter Your Name");
name = scan.nextLine();
System.out.println("Players Name: " + name);
while (true) {
Scanner scan2 = new Scanner(System.in);
System.out.println("Please Enter a Game Name (If You Are Done type \"quit\")");
game = scan.nextLine();
if (game.equals("quit")) {
break;
}
System.out.println("Game: " + game);
Scanner scan3 = new Scanner (System.in);
System.out.println("Please Enter Your Score");
points = scan.nextLine();
System.out.println("Your Score: " + points);
Scanner scan4= new Scanner (System.in);
System.out.println("Please Enter the amount of time Spent Playing in Minutes");
time = scan.nextLine();
System.out.println("Time played: " + time);
}
}
Another alternative is to make use of the for loop, and is more correct for your needs:
for (int i = 0; i < 100; i++) {
//your code
}
Your loop being a simple counter, you might want to replace it with a for-loop as it indicates better that the loop does not break because of some operations happening within the loop:
for(int i = 0 ; i < 100 ; i++) {
// block running 100 times
}
If possible avoid using do / while in favour of a for loop. If the game loop should end when the user types quit, add a break statement.
for (i = 0; i < 100; i++) {
// get user's game choice from console
if (game.equals("quit")){
break;
}
// if they didn't type quit ...
}
This question already exists:
Scanner issue when using nextLine after nextXXX [duplicate]
Closed 8 years ago.
Yes this is an assignment...
I've got 2 arrays; one for student names and one for their scores. I've asked the user to input the number of students to initialize the sizes of both, and then loop through the input process to fill the elements.
But the weirdest thing happens that hasn't happened before. It seems that the student array is cut short by one element when the code is run (after 4 entries the program jumps to the next input loop), but even weirder is that the truncation seems to be at the front of the array, because the scores loop starts with a blank where a name should be but allows for 5 inputs.
import java.util.Scanner;
public class Ex6_17SortStudents {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numOfStu;
String[] students;
double[] scores;
System.out.println("Enter the number of students being recorded: ");
numOfStu = input.nextInt();
students = new String[numOfStu];
System.out.println("Enter students' names: ");
for (int i = 0; i < students.length; i++)
students[i] = input.nextLine();
scores = new double[numOfStu];
for (int i = 0; i < students.length; i++) {
System.out.print("Enter score for " + students[i] + ": ");
scores[i] = input.nextDouble();
}
}
}
Any ideas why this happens?
There's eventually a sort but that's a mess i think i have a handle on.
Sorry if the format for the post is wrong -- first time posting; trying my best.
thanks
This debugging output should give you a clue to your problem:
System.out.println("Enter students' names: ");
for (int i = 0; i < students.length; i++) {
System.out.print("Name index " + i + ": ");
students[i] = input.nextLine();
}
And this answer to this question is exactly the answer you need.
Use students[i] = input.next();
Just checked it, and it works now.
nextLine() advances your scanner past the current line and returns the input that was skipped -- so you were pretty much skipping a line. The first time it enters the loop, you lose an i value, that is i is now 1, yet your scanner does not record user input. The second time around, when i is 1, it takes input, and so forth.
New code:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
int numOfStu;
String[] students;
double[] scores;
System.out.println("Enter the number of students being recorded: ");
numOfStu = input.nextInt();
students = new String[numOfStu];
scores = new double[numOfStu];
System.out.println("Enter students' names: ");
for (int i = 0; i < students.length; i++) {
students[i] = input.next();
}
for (int i = 0; i < students.length; i++) {
System.out.print("Enter score for " + students[i] + ": ");
scores[i] = input.nextDouble();
}
}
My full code is pasted here. Below are the 2 methods that are related to my question.
private static boolean playGameAgain()
{
char playAgain = 'y';
Scanner input = new Scanner(System.in);
while(playAgain != 'n')
{
System.out.println("Go again?(y/n)");
/// PROBLEM HERE.... Somehow, it will NOT wait for INPUT. It just throws an error
playAgain = input.next().charAt(0);
}
input.close();
return (playAgain != 'y')?false:true;
}
// [Trimmed]
public static void initialize(ArrayList<String> names, ArrayList<Integer> scores)
{
Scanner input = new Scanner(System.in);
for (int i = 1; i <= 5; i++)
{
System.out.println("Enter the name for score #" + i + ":");
names.add(input.nextLine());
System.out.println();
System.out.println("Enter the score for score #" + i + ":");
while(!input.hasNextInt())
{
//input.nextLine();
System.out.println("Please input a valid integer value for the score for #" + i + ":");
if(!input.hasNextInt())
input.nextLine();
}
scores.add(input.nextInt());
input.nextLine();
}
input.close();
}
I have tried many combinations of how to read in one character. This used to work, that I could read in one character by using:
Scanner input = new Scanner(System.in);
char temp = input.next().charAt(0);
But, somehow, in this program I wrote, it won't work.
It's a program that will read in 5 user names (strings) & 5 scores (integers) and put them in 2 arrays. It will sort the arrays in descending order and then it will print them out. So, the only problem I have is asking if they want to play again and taking some char input to see if they want to play again (y/n)?
Please help if you can. I've tried many combinations of: if (input.hasNext()), to no avail.
You are not setting playAgain to something other than 'y' in playGameAgain(). You have a bug here.