Java Scanner Breaks when an unknown thing is input - java

I have a program where a scanner is responding to certain things that you type in.
Here is an example of the code:
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
int i=0;
String in = inp.nextLine();
while(i==0){
if(in.equals("x")){
System.out.println("> y");
in = inp.nextLine();
}
}
Everything works fine, like if I type in x, it says y. However, if I type in z, nothing happens, then if I type in x, nothing happens and it completely breaks. What can I do?

You have an infinite loop right so your program is stuck there. Since the second time you enter z which is not equal to x so your code flow doesn't go into the if and get stuck in the infinite loop since your i variable doesn't change either.

You have created infinite loop.
When input is z, check for equalitiy fails and loop keeps spining on condition i == 0 which is always true.

If you want x to continue working after you put in a value that is not accepted take the in = inp.nextLine(); call out like this:
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner inp = new Scanner(System.in);
int i=0;
String in = inp.nextLine();
while(i==0){
if(in.equals("x")){
System.out.println("> y");
//in = inp.nextLine(); remove this
}
in = inp.nextLine();
}
}
Not sure if this is what you were looking for.
Also if you do not plan to change i, you can simply keep the while loop going by doing this.
while(true){
//do stuff here
}

Move this line:
in = inp.nextLine();
outside of the curly braces that it is in.
Also, as others have said you have an infinite loop. One way to fix that is have a sentinel character (like 'q') that it checks for and breaks out if it is detected.

Like everyone said, you're in an infinite loop, and when you type z and the equality check fails, you never enter the if block again to check for user input, so typing x again after z won't print anything.
Assuming you want to keep your program as is and continually ask for input, you can just move the:
in = inp.nextLine();
after the if block.
You may want to have some sort of terminating condition though so the program can exit (like you exit the loop when the user types q or something along those lines).

When you enter z, nothing happens because you did not instruct it to do anything if inpout is not equal to x.
Since the in = inp.nextLine(); is in the if condition, it wont read anything from the keyboard if you do not enter x. So move it outside of the loop.
public static void main(String[] args) {
Scanner inp = new Scanner(System.in);
int i=0;
String in = inp.nextLine();
while(i==0){
if(in.equals("x")){
System.out.println("> y");
}else{
System.out.println("input != x");
}
in = inp.nextLine();
}

Related

hasNextInt won't return false and exit the loop

I'm trying to put user input into an array but the hasNextInt() method will not return false and stop the input.
public static void main (String[] args) {
Scanner in = new Scanner(System.in);
int target = in.nextInt();
while(in.hasNextInt()) {
weights.insert(in.nextInt());
}
recKnapSack(target, 0);
}
Scanner.hasNextInt() will return false when it encounters a non-integer character in its buffer.
However, it may strip out whitespace when it's reading prompts. So Space+Enter or Enter will most likely not stop the loop. But any other character will.
Since you'd like to input any number of ints, you must instruct the user on what to type when they're done. In fact, if you're writing a console application, it's a good idea to always explain WHY a program is waiting for input.
Any non-integer will stop the loop condition. In this case the syntax will work as-is, the user just needs some instruction:
System.out.println("Please enter the target");
int target = in.nextInt();
System.out.println("Enter weights. Type 'X' to stop");
while(in.hasNextInt()) {

Java: how to reject incorrect input and wait for proper input using Scanner

This is the basic setup for a little console-based quiz game. The answers are numbered. I want the player to give the answer number. If the input is not a number, then my program should give a warning, and wait for proper input.
Instead, what I get (after inserting something that is not a number) is an infinite loop of asking the question and presenting the answers again.
public static void main(String[] args) {
boolean quizActive = true;
while(quizActive) {
presentQuestion();
presentAnswers();
Scanner s = new Scanner(System.in);
if (s.hasNext()) {
String choice = s.next();
if (!NumberUtils.isNumber(choice)) {
presentText("Please insert the answer number.");
} else {
System.out.println("You made a choice!");
checkAnswer(choice);
quizActive = false;
}
s.close();
}
}
}
What am I doing wrong here?
If you do not want to question and answers be presented each time move presentQuestion() and presentAnswers() outside the loop.
But main problem is that you closing Scanner.
Remove s.close(); and move Scanner s = new Scanner(System.in); outside of the loop.
I really don't get the point in using scanner for acquiring user input.
The scanner class is perfect to process structured input from a flat file with known structure like an CSV.
But user input need to deal with all the human imperfection. After all the only advantage you get is not needing to call Integer.parseInt() your yourself at the cost to deal with the not cleared input when scanne.nextInt() fails...
So why not using InputStreamReader aside with a loop suggested by others?
Here an Example :
public class Application {
public static void main(String [] args) {
System.out.println("Please insert the answer number. ");
while (true) {
try {
Scanner in = new Scanner(System.in);
int choice = in.nextInt();
System.out.println("You made a choice!");
checkAnswer(choice);
break;
} catch (Exception e) {
System.out.println("Invalid Number, Please insert the answer number ");
}
}
}
}
You started your Quiz in a loop which is regulated by your quizActive boolean. That means that your methods presentQuestion() and presentAnswers() get called every time the loop starts again.
If you don't input a number but a character for example, your program will run the presentText("Please insert the answer number.") and start the loop again. As it starts the loop again, it will call the methods presentQuestion() and presentAnswers().
To stop that, you can do another loop around the input-sequence. Also your Scanner s = new Scanner(System.in) should be outside the loop. And you shouldn't close your Scanner right after the first input and then open it again!
if you want a code example, please tell me :)

Can still enter input even outside loop

Why is that I can still an input even it's outside the while loop?
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String input = scan.next();
while(true){
}
}
First, you don't need a while loop to take any input and your loop is practically useless since its not being used. Second, That loop is bad since any other loops you might have in your code will be unreachable. unless you specify a way to break the loop using break; or flags e.g.:
boolean myCondition = true;
while(myCondition){}
or use break:
while(true){
if(whatever){
break;
}
}
Then again you don't need any of this since your not dealing with multiple inputs etc. So your answer is NO its working how you told it to work.

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.

Using a while loop in an ArrayList

I'm new to programming and to this website, so here goes.
I wanted to write a program that would allow as many input strings as possible to be added to an ArrayList. So I used a while loop in the following code. What I intended was for the loop to break if the input was 0.
import java.util.*;
public class AddToList2
{
static Scanner q = new Scanner(System.in);
public static void main(String[] args)
{
ArrayList<String> inputlist = new ArrayList<String>();
while (true)
{
System.out.print("Enter something here: ");
String x = q.nextLine();
inputlist.add(x);
if (x.equals("0"));
break;
}
}
The program was compiled without error, but sadly, when I ran the program many times, the loop broke no matter what the input was. Any way to solve this?
Well, that was careless of me! Anyway, I had created that program in order to find out what was wrong with this:
ArrayList<String> endangeredlist = new ArrayList<String>();
ArrayList<Integer> popn = new ArrayList<Integer>();
while (true)
{
System.out.print("Name an animal: ");
String animal = q.nextLine();
endangeredlist.add(animal);
if (animal.equals("EXTERMINATE"))
break;
q.next();
System.out.print("How many are left in the wild? ");
int numberleft = q.nextInt();
popn.add(new Integer(numberleft));
}
(This is part of a much larger program.) My intention was for the loop to break when the animal name input was EXTERMINATE. Sadly the program throws a NoSuchElement exception if the input first time round was EXTERMINATE, and if I had inputted something else first the loop would start, but then inputting EXTERMINATE second time round does not break the loop. Why is that?
You have an extraneous semicolon after your if, which effectively makes it
if (x.equals("0")) { }
break;
You have a semi-colon at the end of your condition.
This turns the break into a statement of its own, without the condition.
Your if statement is broken
if (x.equals("0"));
This is basically saying if (x.equals("0")) do nothing...
This is one of the reasons why you should use parenthesis around your if statements
if (x.equals("0")) {
break;
}

Categories

Resources