hasNextDouble(), my program stops without crashing and without looping - java

My program seems stuck in the middle of my while loop, without crashing and without looping infinitely. It just stops.
The loop runs for as many input as the user provides, but then does not move on the the next line of code.
It is my first time using the hasNextDouble() in java. Am I doing it right?
Here is the while loop in question:
System.out.print("Grades (separated by a space)");
while(in.hasNextDouble())
{
student1.addGrade(in.nextDouble());
}
And here is a little bit more of my code:
Scanner in = new Scanner(System.in);
String input = "";
Student student1 = new Student();
GradeBook book = new GradeBook();
// Sets the name of the first student
System.out.print("Name: ");
input = in.nextLine();
student1.setNames(input);
// Sets the grades of the first student
System.out.print("Grades (separated by a space)");
while(in.hasNextDouble()){
student1.addGrade(in.nextDouble());
}
// Put the student into the GradeBook
book.addStudent(student1);
// Prints the report
System.out.print(book.reportGrades());

You state you want space separated input, in a single line. I would suggest taking the input as a String, and then splitting it up, like
Scanner in = new Scanner(System.in);
String line = in.nextLine();
for(String s : line.split(" ")){
student1.addGrade(Double.parseDouble(s)); //gives exception if value is not double
}
Scanner.hasNextDouble will continue to return true, until you enter a non-Double value.

With hasNext() you check if there is anything, then with hasNextDouble() check if the next input can be cast to double. You read the value with next(), but the value is still a string, so you need to parse it to double.
Also, you need a way to get out of the loop with break when input is no longer a number.
while (in.hasNext()) {
if (in.hasNextDouble()) {
student1.add(Double.parseDouble(in.next()));
} else {
break;
}
}

Related

While Loop Not Closing When Condition Is Met

public void enroll() {
Scanner in = new Scanner(System.in);
System.out.println("Enter course to enroll (Q to quit)");
while(!in.nextLine().equals("Q")) {
courses.add(in.nextLine());
}
}
The program should accept user input and add it to the ArrayList courses until the user enters "Q" but instead what's happening is that it seems like it's only registering and adding every other input. It's also adding the Q which is an issue.
Your code doesn't do what you want it to do.
How it should be: users inputs are processed one per iteration and if it's 'Q', then quit while.
How it actually is: users inputs are processed two per iteration(because you cal in.nextLine() both in conditional part and in body of while), and if first is not 'Q' then add second to list.
Here is my code to this:
Scanner in = new Scanner(System.in);
System.out.println("Enter course to enroll (Q to quit)");
String line;
while(!(line = in.nextLine()).equals("Q")) {
courses.add(line);
}
Your issue is that you are getting the next line twice, firstly inside the loop condition while(!in.nextLine().equals("Q")) { then again inside the loop courses.add(in.nextLine());.
One solution could be to use a string variable to store the line, and an if check to see if the condition is met:
public void enroll() {
Scanner in = new Scanner(System.in);
System.out.println("Enter course to enroll (Q to quit)");
String line = "";
while(true) {
//We should only get the next line once per loop:
line = in.nextLine();
//Now we can use the line
if (line.equals("Q")){
break;
}
courses.add(line);
}
}

Why do I have to write twice to add an input in the Arraylist?

public static void main(String[] args) {
List<String> arrayList = new ArrayList<>();
Scanner input = new Scanner(System.in);
do {
System.out.println("Enter a product");
String product = input.nextLine();
arrayList.add(product);
}
while (!input.nextLine().equalsIgnoreCase("q"));
System.out.println("You wrote the following products \n");
for (String naam : arrayList) {
System.out.println(naam);
}
}
I'm trying to get some input from the user and store them into arraylist. The problem is I have to write the item twice to add an item into the list. I can't figure out why!
Instead of do-while loop use only while
while (true){
System.out.println("Enter a product");
String product = input.nextLine();
if (!product.equalsIgnoreCase("q"))
arrayList.add(product);
else
break;
}
Every time you write readLine(), a line is read. In this loop,
do {
System.out.println("Enter a product");
String product = input.nextLine();
arrayList.add(product);
}
while (!input.nextLine().equalsIgnoreCase("q"));
There are two occurrences of readLine(), so two lines are read every iteration. The first line is always added to the list and not checked against q, and the second is never added to the list, and always checked against q.
You should only do nextLine once:
while (true) {
System.out.println("Enter a product");
String product = input.nextLine(); // only this one time!
if (!product.equalsIgnoreCase("q")) {
arrayList.add(product);
} else {
break;
}
}
It happenes coz input.nextLine() makes java read the input. You should read the line and only then do the stuff:
Scanner input = new Scanner(System.in);
String product = input.nextLine();
System.out.println("Enter a product");
while (!product.equalsIgnoreCase("q")) {
arrayList.add(product);
System.out.println("Enter a product");
product = input.nextLine();
}
You can read the String values using input.next() once and have a while loop in place and read further values into your list only if the value is not equal to q.
If you have read it twice as in your case, one value is added to the list in your do part, and the value you read again in your while part is only compared to q and so to exit your code, you will be missing one value and adding another and have to give two q values one after another to exit it.
Also, since most of the other users have given there answers with nextLine instead of next you may want to check what next does and what nextLine does. In brief, if you enter names of products separated by a delimiter (default space), then with next, each value separated by the space is considered a product. Similarly, if you enter on different line as well. But, with nextLine, each line as a whole will be added as a new product. It depends on how you may want to achieve this as per your requirement.
public static void main(String[] args) {
List<String> arrayList = new ArrayList<>();
Scanner input = new Scanner(System.in);
String product = input.next();
while(!product.equalsIgnoreCase("q")) {
arrayList.add(product);
product = input.next();
}
System.out.println("You wrote the following products \n");
for (String naam : arrayList) {
System.out.println(naam);
}
}

How to stop scanning after I input a certain line?

I want to build a program that only stops scanning for strings until after I input "0" in the console, how do I do that?
I assume I can use do while loop, but I don't know what to put in the while() condition.
Scanner scan = new Scanner(System.in);
do {
String line = scan.nextLine();
//do stuff
} while(); //what do i put in here to stop scanning after i input "0"
Thanks in advance, I'm new to Java and OOP in general.
You can use a while loop instead of a do-while loop. Define a String that will be initialized inside the while loop. On each iteration we assign the String to Scanner#nextLine and check if that line is not equal to 0. If it is, the while-loop prevents iteration.
Scanner scan = new Scanner(System.in);
String line;
while (!(line = scan.nextLine()).equals("0")) {
System.out.println("line: " + line);
}
You don't have to use any loop , as you said you want to stop input when 0 is pressed by default for nextLine() the input stops when user press the enter key because it is the delimiter , so just change the delimiter
Scanner scanner = new Scanner(System.in);
scanner.useDelimiter("0"); //regex
String s = scanner.next(); // no matter what user enters the s will contain the input before 0

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.

Array value not getting populated

In this below program user enters the number of city name to be inserted and then a String array is initialized with that size.Then I try to iterate through loop and initialize every index of array with the value(City Name) inserted from user.
But when I tried to print value from array it ask for one less value..What I mean is if i say number of city is 2 ,so my loop should be iterated twice and twice I should insert value but instead i get to insert value only once.
On debugging i realized that the 0th element is getting inialized by itself from somewhere.I am not able to find the exact problem .
import java.util.Scanner;
public class EmptyStringGenerator {
public static void main(String []ard) {
Scanner scanner = new Scanner(System.in);
System.out.println("How many cities?");
String[]favoriteCities = new String[scanner.nextInt()];
for(int i=0;i<favoriteCities.length;i++){
favoriteCities[i]=scanner.nextLine();
}
for(String str:favoriteCities){
System.out.print(str+" ");
}
}
}
My Input:
2
Delhi
Output:
Delhi
The issue is that you read the int with nextInt(), but don't consume the line end! The rest of the line is left unprocessed, and the next nextLine() call goes on from that point.
nextLine() doc
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.
To correct the issue:
String[]favoriteCities = new String[scanner.nextInt()]; //read int
//consume line end, and do nothing with it
scanner.nextLine();
//now read the cities.
for(int i=0;i<favoriteCities.length;i++){
favoriteCities[i]=scanner.nextLine();
}
Recommended reading:
Scanner Java API doc
Line 0 is the end line after "2". nextInt() does not read that. Add a dummy nextLine() after reading the number.
Use next() method instead of nextLine().Since nextLine() reads the new line skipped by the nextInt() method .
nextLine()
Advances this scanner past the current line and returns the input that was skipped
next()
Finds and returns the next complete token from this scanner
So the code will be now
public static void main(String []ard)
{
Scanner scanner = new Scanner(System.in);
System.out.println("How many cities?");
String[]favoriteCities = new String[scanner.nextInt()];
for(int i=0;i<favoriteCities.length;i++)
{
favoriteCities[i]=scanner.next();
}
for(String str:favoriteCities)
{
System.out.print(str+" ");
}
}
If I understand the OP question correctly, input is int and city name, and the output should be number of times (int) the city name, say e.g 2 Delhi output Delhi Delhi, but he is getting only Delhi.
SOLUTION
String[]favoriteCities = new String[scanner.nextInt()];
String cityToBeAdded = scanner.next();
for(int i=0;i<favoriteCities.length;i++){
favoriteCities[i]=cityToBeAdded;
}
for(String str:favoriteCities){
System.out.print(str+" ");
}

Categories

Resources