Java Infinite loop - java

Can someone please advise why the inner loop of the code below will not exit?
I've added an inner loop to check if input from the user of of a particular value and if not prompts for the correct input. When debugging the code and passing in a value which should force the loop to end it doesn't although I can see the correct value in the variable:
while (finished.equalsIgnoreCase("n")) {
System.out.println("Enter a persons name");
names = in.nextLine();
writer.println(names);
System.out.println("Finished? (Y/N)");
finished = in.nextLine();
while( !finished.equalsIgnoreCase("y") || !finished.equalsIgnoreCase("n")) {
System.out.println("Invalid choice; (Y/N)");
finished = in.nextLine();
}
}

Every string is either not not equal to y or not equal to n. You probably meant to use the && operator:
while(!finished.equalsIgnoreCase("y") &&
!finished.equalsIgnoreCase("n")) {
// Code...

Related

Simple Do-while loop in Java

I want to run a loop and continue to accept a string input until "x" is pressed. I'm trying following do-while loop, but it doesn't get in the loop, it runs only once.
Scanner sc = new Scanner(System.in);
String name;
do {
System.out.print("Enter name or 'x' to quit: ");
name = sc.next();
if (name.equals("x")) {
break;
}
System.out.printf("The name is %s", name);
} while (name.equals("x"));
You need to remove if condition so that it doesn't break out of the loop early and modify the break condition, e.g.:
Scanner sc = new Scanner(System.in);
String name;
do {
System.out.print("Enter name or 'x' to quit: ");
name = sc.next();
System.out.printf("The name is %s", name);
} while (!name.equals("x"));
It continues looping when "x" is pressed. So you did the exact opposite.
Add an exclamation mark to negate your while condition:
while (!name.equals("x"))
I might be missing something, but it seems like your code contradicts itself.
You read user input and then check if it equals to x and breaks the loop in that case. If it does not, you continue until the while statement, where x gets checked again for the same condition.
So in summary, you break the loop for the same condition you have for it to run.
You might want to try, changing your condition in the while statement to
while (!name.equals("x"))

How to prevent Java scanner from inputing spaces

I'm trying to prevent the user from inputting spaces or no values.
but nothing works. Even with no entered values program goes further without printing my error. What am I doing wrong?
my code example
Scanner nameScan = new Scanner(System.in);
System.out.print("Input your name: ");
String newcomer = nameScan.nextLine();
player.setName(newcomer);
String userName = player.getName();
userName = userName.trim();
if (userName.length()==0) {
System.out.println(" ");
System.out.println("You have to set up a player name first... ");
System.out.println(" ");
}
else {...
As #11thdimension said, you have to validate the input.
You can do something like:
if (newcomer.isEmpty()) {
System.out.println("Please write something");
}
Or you can do a while loop and keep asking for a correct input.
Your code
if(username.length() == 0)
will not check whether the username contains space because space is counted towards the length of the String.
To check for empty String input(which may contain space(s)), you can do:
if("".equals(username.replaceAll("\\s+",""))) //or
if("".equals(username.trim()) //or
if(username.isEmpty())
Further more, you would want to use a do-while loop for validation instead of using an if-statement.

user input within while loop

I was asked to run a loop that asks for user input, applies the change using the adjustPrice() method, print the new information after adjusting the price. and then finishes the loop when the user enters 0.
Right now it does all of the above, just doesn't ask for the user input again and ends with the printed new information. please help!
boolean done = false;
while (!done) {
System.out.print("Enter adjustment to price in percent (0 to quit): ");
double adjustment = in.nextDouble();
if (adjustment == 0) {
done = true;
}else{
swag.adjustPrice(adjustment);
System.out.println(swag.toString());
in.next();
}
}
You have in.next() at the end. This expects the user to input something before the loop will reset to the System.out line. Take out that line.
to allow user input using the end
else {
swag.adjustPrice(adjustment);
System.out.println(swag.toString());
in.next();
}
but beware that this method does not take keys as enter or space to
take into account these keys use.
else {
swag.adjustPrice(adjustment);
System.out.println(swag.toString());
System.in.read();
}

How to fix my Java code for validating variables?

I'm currently doing a project in my computer science class and we are suppose to validate each character of a variable to see if it is legal or not. If it starts with a number it's illegal. If it starts with a special character it's legal but bad style. If it has a space it is again illegal. I'll post my current code now:
import java.util.Scanner;
public class classOfValidation {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String theVariable = null;
System.out.println("This program checks the validity of variables");
System.out.println("Please enter a variable (or press 'q' to quit");
theVariable = scan.nextLine();
do {
System.out.println("The variable is illegal");
theVariable = scan.nextLine();
} while (theVariable.startsWith("[0123456789]"));
do {
System.out.println("The variable is illegal");
theVariable = scan.nextLine();
} while (theVariable.contains("[ ]"));
do {
System.out.println("The variable is legal, but has bad style");
theVariable = scan.nextLine();
} while (theVariable.startsWith("[!##$%^&*]"));
}
}
If you couldn't already tell i'm new to programming and as confused as i possibly could be. If you have any advice or anything else you need me to explain then please leave a comment. Thanks everyone
You can use the single regex to validate your input via String#matches() method. But as for the example you've provided, you should use while loop, but not do-while, because in do while case, you are always running it's body once befor condition checked. So, you better do it like:
theVariable = scan.nextLine();
while (theVariable.startsWith("[0123456789]")) {
System.out.println("The variable is illegal");
theVariable = scan.nextLine();
}
while (theVariable.contains("[ ]")) {
System.out.println("The variable is illegal");
theVariable = scan.nextLine();
}
while (theVariable.startsWith("[!##$%^&*]")) {
System.out.println("The variable is legal, but has bad style");
theVariable = scan.nextLine();
}
The second, in your solution, you are using String.startsWith() method and passing into it some regex. Take a look at javadoc for this method. It's said there:
Tests if this string starts with the specified prefix.
That means, that this method doesn't support regexes, but simply checks whether the string starts with the passed string. So, your conditions seems, never to become true. I don't think, someone will input the [0123456789] or [!##$%^&*].
One more, any conditions are checked once, but after that user can modify the input and the previewsly passed condition will not be checked again. Seems, it's better to run into infinite loop with continue and break in some conditions, like:
//infinit loop, until user enter the `q` or the input is correct
while (true) {
//read the input
theVariable = scan.nextLine();
//chtck, whether is `quit` command entered
if ("q".equals(theVariable)) {
break;
}
//if string starts with digit or contains some whitespaces
//then print alert and let the user to
//modify the input in a new iteration
if (theVariable.matches("^\d+.*|.*\s+.*")) {
System.out.println("The variable is illegal");
continue;
}
//if string contains some special characters print alert
//and let the user to modify the input in a new iteration
if (theVariable.matches("^[!##$%^&*].*")) {
System.out.println("The variable is legal, but has bad style");
continue;
}
//if all the conditions checked, then break the loop
break;
}
I think the best way if you are use regex.
Here is an answer how to do that.

Java .nextLine() repeats line

Everything of my guessing game is alright, but when it gets to the part of asking the user if he/she wants to play again, it repeats the question twice. However I found out that if I change the input method from nextLine() to next(), it doesn't repeat the question. Why is that?
Here is the input and output:
I'm guessing a number between 1-10
What is your guess? 5
You were wrong. It was 3
Do you want to play again? (Y/N) Do you want to play again? (Y/N) n
Here is the code:(It is in Java)
The last do while loop block is the part where it asks the user if he/she wants to play again.
import java.util.Scanner;
public class GuessingGame
{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
boolean keepPlaying = true;
System.out.println("Welcome to the Guessing Game!");
while (keepPlaying) {
boolean validInput = true;
int guess, number;
String answer;
number = (int) (Math.random() * 10) + 1;
System.out.println("I'm guessing a number between 1-10");
System.out.print("What is your guess? ");
do {
validInput = true;
guess = input.nextInt();
if (guess < 1 || guess > 10) {
validInput = false;
System.out.print("That is not a valid input, " +
"guess again: ");
}
} while(!validInput);
if (guess == number)
System.out.println("You guessed correct!");
if (guess != number)
System.out.println("You were wrong. It was " + number);
do {
validInput = true;
System.out.print("Do you want to play again? (Y/N) ");
answer = input.nextLine();
if (answer.equalsIgnoreCase("y"))
keepPlaying = true;
else if (answer.equalsIgnoreCase("n"))
keepPlaying = false;
else
validInput = false;
} while (!validInput);
}
}
}
In your do while loop, you don't want the nextLine(), you just want next().
So change this:
answer = input.nextLine();
to this:
answer = input.next();
Note, as others have suggested, you could convert this to a while loop. The reason for this is that do while loops are used when you need to execute a loop at least once, but you don't know how often you need to execute it. Whilst it's certainly doable in this case, something like this would suffice:
System.out.println("Do you want to play again? (Y/N) ");
answer = input.next();
while (!answer.equalsIgnoreCase("y") && !answer.equalsIgnoreCase("n")) {
System.out.println("That is not valid input. Please enter again");
answer = input.next();
}
if (answer.equalsIgnoreCase("n"))
keepPlaying = false;
The while loop keeps looping as long as "y" or "n" (ignoring case) isn't entered. As soon as it is, the loop ends. The if conditional changes the keepPlaying value if necessary, otherwise nothing happens and your outer while loop executes again (thus restarting the program).
Edit: This explains WHY your original code didn't work
I should add, the reason your original statement didn't work was because of your first do while loop. In it, you use:
guess = input.nextInt();
This reads the number off the line, but not the return of the line, meaning when you use:
answer = input.nextLine();
It immediately detects the leftover carriage from the nextInt() statement. If you don't want to use my solution of reading just next() you could swallow that leftover by doing this:
guess = input.nextInt();
input.nextLine();
rest of code as normal...
The problem really lies in a completely different segment of code. When in the previous loop guess = input.nextInt(); is executed, it leaves a newline in the input. Then, when answer = input.nextLine(); is executed in the second loop, there already is a newline waiting to be read and it returns an empty String, which activates the final else and validInput = false; is executed, to repeat the loop (and the question).
One solution is to add an input.nextLine(); before the second loop. Another is to read guess with nextLine() and then parse it into an int. But this complicates things as the input could not be a correct int. On a second thought, the code already presents this issue. Try entering a non-numeric response. So, define a function
public static int safeParseInt(String str) {
int result;
try {
result= Integer.parseInt(str) ;
} catch(NumberFormatException ex) {
result= -1 ;
}
return result ;
}
And then replace your first loop with:
do {
validInput= true ;
int guess= safeParseInt( input.nextLine() ) ;
if( guess < 1 || guess > 10 ) {
validInput= false ;
System.out.print("That is not a valid input, guess again: ");
}
} while( !validInput );
PS: I don't see any problem with do-while loops. They are part of the language, and the syntax clearly indicates that the condition is evaluated after the body is executed at least one time. We don't need to remove useful parts of the language (at least from practice) just because others could not know them. On the contrary: if we do use them, they will get better known!
validInput = false;
do {
System.out.print("Do you want to play again? (Y/N) ");
answer = input.next();
if(answer.equalsIgnoreCase("y")){
keepPlaying = true;
validInput = true;
} else if(answer.equalsIgnoreCase("n")) {
keepPlaying = false;
validInput = true;
}
} while(!validInput);
I changed the coding style as I find this way more readable.
Your problem is that nextInt will stop as soon as the int ends, but leaves the newline in the input buffer. To make your code correctly read the answer, you'd have to enter it on the same line as your guess, like 5SpaceYReturn.
To make it behave more than one would expect, ignore the first nextLine result if it contains only whitespace, and just call nextLine again in that case without printing a message.
I believe the output of input.nextLine() will include the newline character at the end of the line, whereas input.next() will not (but the Scanner will stay on the same line). This means the output is never equal to "y" or "n". Try trimming the result:
answer = input.nextLine().trim();

Categories

Resources