How to stop scanning after I input a certain line? - java

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

Related

reading multiple lines of input always runs an infinite loop unless I print each line

I'm trying to process multiple lines of input from the console using a Scanner in Java, and it runs in an infinite loop unless I print out each line. For some reason the next line is not 'consumed' unless I print it. I don't want to print it, I only want to add each line to an array to process later, so I don't know how to 'consume' each line w/o printing it. Both of these loops are infinite:
while(sc.hasNext()) {
String line = sc.nextLine();
commands.add(line);
//System.out.println(line);
sc.nextLine();
}
while(sc.hasNext()) {
String line = sc.nextLine();
commands.add(line);
//System.out.println(line);
//sc.nextLine();
}
EDIT:
My scanner initialization is below, and I also edited the condition to hasNextLine(), still running an infinite loop. That print statement that prints "done" never excecutes.
Scanner sc = new Scanner(System.in);
ArrayList<String> commands = new ArrayList<String>();
while(sc.hasNextLine()) {
String line = sc.nextLine();
commands.add(line);
//System.out.println(line);
//sc.nextLine();
}
System.out.println("done");
You should be calling hasNextLine(), not hasNext().
Printing has nothing to do with it. Printing doesn't terminate loops.
EDIT If you are never seeing your final "done", this isn't an infinite loop at all, it is a block: you're never sending an end of stream to System.in. Type Ctrl/d or Ctrl/z depending on Windows vs. Unix/Linux/... and again, printing has nothing to do with it.

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

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;
}
}

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.

Java - if/else fails immediately when supposed to pause

I'm having troubles with a function in java. Here's my code:
do{
System.out.print("Proceed to payment? (y/n) ");
input = scan.nextLine();
if((input.trim()).equals("y")){
break;
}
else if((input.trim()).equals("n")){
System.out.print("Come back next time, " + name + ".");
System.exit(0);
}
else{
System.out.println("Invalid response. Try again.");
}
}
while(true);
Basically, the first time the function loops it 'skips' the "input = scan.nextLine" and immediately prints "Invalid response. Try again." to the terminal. It then allows the user to input something, and works normally.
Yes, I have declared input, scan (java.util.Scanner;), and name earlier in my code. It'd be a great help if someone can point out what I've done wrong! Thanks!
While adding scan.nextLine() before does help, I keep a general rule of setting the delimiter whenever I initialize the Scanner class by using:
scan.useDelimiter("\n");
in this case, which uses a newline as a delimiter. As a result, for all the methods of scan, whenever the user presses Enter, it is interpreted as the end of the input. This includes, nextInt(), nextDouble(), next()etc...
Using the delimiter also means that I don't have to add scan.nextLine() after every non-nextLine() input.
You probably called scan.next(), or something like that, before entering the do-while loop. That left a next line character in the input, and the call to scan.nextLine() consumed it. To fix it, you could place a scan.nextLine() call right after scan.next() so it will consume the next line before entering the loop.
For example:
Scanner scan = new Scanner(System.in);
String input;
String name = scan.next();
scan.nextLine();
do {
System.out.print("Proceed to payment? (y/n) ");
input = scan.nextLine();
// rest of the code
}
while(true);

Java Scanner won't "finish" reading input

I've been having trouble using java's Scanner class. I can get it to read my input just fine, but the problem is when I want to output something. Given multiple lines of input, I want to print just ONE line when all the input has been read completely. Here's the code I use for reading input:
public static void main(String[] args){
Scanner scanner = new Scanner(System.in); //scanner reads block of input
while(scanner.hasNextLine()){
//body of loop goes here
String s = scanner.nextLine();
Scanner ls = new Scanner(s); //scanner to parse a line of input
while(ls.hasNext()){
//body of nested loop goes here
ls.next();
}
}
System.out.println("Fin");
}
Even when all lines of input have been read, the program doesn't reach the System.out.println message. (Note that the message can't go anywhere else or it will output as many times as the loop is run). How do I fix this? Any help would be greatly appreciated.
As I can see in your outer while loop you have used
scanner.hasNextLine();
method. This method gets blocked if it has to wait for the input. Also you have
Scanner scanner = new Scanner(System.in);
statement. So the system.in will be waiting for input all the time, hence the hasNextLine() method has to wait for the input.
That is why the control gets stuck in the loop and can't proceed further.
To fix it you can first store input in a string variable and the call the scanner constructor on it.
You are reading from an Infinite stream in this case. hasNextLine() will keep returning true if there is another line in the input of this scanner. As its a System.in, it will keep reading from the Keyboard, unless you terminate it or tell the stream to stop.
Press "ctrl+Z" in the end, you will see that it works.
Edit : You could do something like this...
Scanner scanner = new Scanner(System.in); //scanner reads block of input
int BLOCK_SIZE =3,count=1;
while(scanner.hasNextLine()){
//body of loop goes here
String s = scanner.nextLine();
Scanner ls = new Scanner(s); //scanner to parse a line of input
while(ls.hasNext()){
//body of nested loop goes here
ls.next();
}
if(count++==BLOCK_SIZE)
{
break;
}
}
System.out.println("Fin");
}
You need to tell the program that there is going to be no more input. This is done by appending an EOF character. This can be done manually on Linux by pressing Ctrl-D in the console. I think on Windows you can press Ctrl-Z. The stream will be automatically closed if you are piping input from one program to another.
eg.
cat filename | java MyJavaProgram
The magic of
Scanner scanner = new Scanner(System.in);
while(scanner.hasNextLine()){
Is that there will never stop being input from System (unless you close the input with ctrl+d (for macs)).
To stop the loop, I suggest throw something more in the condition than just hasNextLine().
E.g.
Scanner scanner = new Scanner(System.in); //scanner reads block of input
int BLOCK_SIZE =3,count=1;
while(scanner.hasNextLine() && count++ <= BLOCK_SIZE){ //<- Use count here.
//body of loop goes here
String s = scanner.nextLine();
Scanner ls = new Scanner(s); //scanner to parse a line of input
while(ls.hasNext()){
//body of nested loop goes here
ls.next();
}
}
System.out.println("Fin");
}

Categories

Resources