Im trying to write code for a school project, the main objective is to get the average gpa of a students semester depending on how many Subjects and Units you input, however, if I try typing 0, the program goes into an infinite try-catch loop with "You can only type positive numbers" Im using valueOf() because I want the user to be able to type "salir" which means exit, to exit the program.
Scanner LeerTeclado = new Scanner(System.in);
int n=0, i=0, suma=0, promedio=0;
String materia, cadena;
//---------------------------------------------------------------------------
out.println("---------------------------");
out.println("-- School Grades --");
out.println("---------------------------");
//---------------------------------------------------------------------------
out.println("\nType 'salir' to terminate the program");
out.println("-----------------------------------------");
out.print("Type the number of subjects to grade: ");
cadena = LeerTeclado.nextLine();
int z = 0;
if("salir".equals(cadena)){
System.exit(0);
}
if("Salir".equals(cadena)){
System.exit(0);
}
///////////////////////////////////////////////////////////////////
do{
try{
z = Integer.valueOf(cadena);
if(z <= 0){
out.println("...............................................");
out.println(" You can only type positive numbers ");
out.println("...............................................");
out.println("\n");
continue;
}
break;
}catch(NumberFormatException ex){
out.println("\n*You have entered non-numeric characters*");
out.print("\nPlease type the number of subjects again: ");
LeerTeclado.nextLine();
}
}while(true);
In the try block, before you write
continue;
but after "You can only type positive numbers," you should prompt the User for another line of input, and wait for the user to enter that.
The "continue" statement skips to the end of the loop and causes the 2nd part of the loop not to run. That is why the loop is running indefinitely.
Move reading cadena into the try block
int z = 0;
do {
try {
cadena = LeerTeclado.nextLine(); // <-- re-read
if ("salir".equalsIgnoreCase(cadena)) { // <-- you might test once.
System.exit(0);
}
// if ("Salir".equals(cadena)) {
// System.exit(0);
// }
z = Integer.valueOf(cadena); // <-- or this loops forever.
Alberto,
There are a few things that need to be changed in order to get this program to work the way you wish. Since you are a student I'm not going to solve it for you. I will answer your question, however.
When you type zero on the command line your program will execute from the z<=0 test down to the continue statement. The continue statement tells the code to ignore everything after and return to the beginning of the loop so it goes back to the beginning of the do statement and repeats. You need some way to end the loop.
May I suggest writing the program a little at a time and test as you go along. That is, write the part that's not in the loop. Once that works write a little something in the loop and test. Keep doing this until the programs works the way you want it to.
Good Luck
do{
try{
z = Integer.valueOf(cadena);
if(z <= 0){
out.println("...............................................");
out.println(" You can only type positive numbers ");
out.println("...............................................");
out.println("\n");
continue;
}
You want to use break
if(z <= 0){
System.out.println("...............................................");
System.out.println(" You can only type positive numbers ");
System.out.println("...............................................");
System.out.println("\n");
break;
}
continue just hops to the top of the if and keeps at it, same thing.
Related
I wasn't sure how to give a title for this problem, but basically this is part of my blackjack program. Also, since I did not know how to title this, I wasn't sure how to look it up, which is why I am asking here. So I am saying that when the user enters either 1 or 11 for the ace value, if they enter something other than 1 or 11, it asks the user again to put in 1 or 11. In my program everything works fine except when the user enters 1, then it just asks the question again. The program should only asks again if the input is not equal to 1 or 11. Here is my code as I made sure it always gives an ace for testing purposes:
String card1="A";
int total=0;
Scanner input_var=new Scanner(System.in);
if (card1=="A"){
System.out.println("Do you want a 1 or 11 for the Ace?: ");
int player_ace_selection=input_var.nextInt();
if ((1|11)!=(player_ace_selection)){
System.out.println("Please enter a 1 or 11: ");
int new_selection=input_var.nextInt();
total=total + new_selection;
}
else {
total=total + player_ace_selection;
}
}
System.out.println(total);
Thanks in advance.
The expression (1|11) uses binary OR, which produces 11:
11 = 01001
1 = 00001
(11|1) = 01001
Hence, the comparison is the same as 11!=player_ace_selection
You should change the code to use logical OR, i.e.
if (1!=player_ace_selection && 11!=player_ace_selection) {
...
}
In addition, you need to fix card1 == "A" comparison for card1.equals("A")
Instead of an If statement, try a while loop. A while loop ensures that your program waits for your user to pick the right answer. You also made a mistake with your logical operations. The correct way to use "OR" in this context is to compare your user input to both '1' and '11' separately using '||'.
String card1="A";
int total=0;
Scanner input_var=new Scanner(System.in);
if (card1.equals("A")){
System.out.println("Do you want a 1 or 11 for the Ace?: ");
int player_ace_selection=input_var.nextInt();
while(player_ace_selection != 1 && player_ace_selection != 11){
System.out.println("Do you want a 1 or 11 for the Ace?: ");
player_ace_selection = input_var.nextInt();
}
total += player_ace_selection;
}
System.out.println(total);
There are some problems in your code, please consider this example and compare it with yours.
String card1="A";
int total=0;
Scanner input_var=new Scanner(System.in);
if (card1.equals("A")){ // compare the content not the reference (==)
System.out.println("Do you want a 1 or 11 for the Ace?: ");
try{ // wrap with try-catch block
int player_ace_selection = Integer.parseInt(input_var.nextLine()); //read the entire line and parse the input
if ((player_ace_selection!=1)&&(player_ace_selection!=11)){
System.out.println("Please enter a 1 or 11: ");
try{
int new_selection = Integer.parseInt(input_var.nextLine()); //again read the entire line and parse the input
total=total + new_selection;
}catch(NumberFormatException e){
// do something to catch the error
}
}
else {
total=total + player_ace_selection;
}
}catch(NumberFormatException e){
// do something to catch the error
}
System.out.println(total);
}
Good evening,
I'm at a loss as to why this loop isn't working at all. It's ruining my entire application. below is the code:
System.out.println("Please tell me what to count till?");
do
{
try
{
newEndingValue= input.nextInt();
if(newEndingValue >= 0 || newEndingValue <= 0)
{
break; //breaks the loop
}
}
catch (InputMismatchException e)
{
System.out.println("My Apologies, but COMMAND NOT RECOGNIZED!" + "\nPlease tell me what to count till?");
input.next();
}
}
while(!input.hasNextInt());
v.setEndingValue(newEndingValue);
System.out.println("Please tell me what to count from?");
if(increasingOrDecreasing.equalsIgnoreCase("Increasing")|| increasingOrDecreasing.equals("++") || increasingOrDecreasing.equals("+"))
{
do
{
try
{
newInitialValue = input.nextInt();
if(newInitialValue < v.getEndingValue())
{
break;
}
else{
System.out.println("My Apologies, but starting point value must be smaller than ending point value!" + "\nPlease tell me what to count from?");
newInitialValue = (v.getEndingValue()+10);//overrides the value to something that forces the loop back
}
}
catch (InputMismatchException e)
{
System.out.println("My Apologies, but COMMAND NOT RECOGNIZED!" + "\nPlease tell me what to count from?");
input.next();
}
}
while(!input.hasNextInt() || newInitialValue > v.getEndingValue());
}
else
{
do
{
try
{
newInitialValue = input.nextInt();
if(newInitialValue > v.getEndingValue())
{
break; //breaks the loop
}
else{
System.out.println("My Apologies, but starting point value must be larger than ending point value!" + "\nPlease tell me what to count from?");
newInitialValue = (v.getEndingValue()-10);//overrides the value something that forces the loop back
}
}
catch (InputMismatchException e)
{
System.out.println("My Apologies, but COMMAND NOT RECOGNIZED!" + "\nPlease tell me what to count from?");
input.next(); //consumes the erroneously typed string value
newInitialValue = (v.getEndingValue()-10);
}
}
while(!input.hasNextInt() || newInitialValue < v.getEndingValue());
}
So the output is when entered a no, and then 1000 as follows:
Please tell me what to count till?
no
My Apologies, but COMMAND NOT RECOGNIZED!
Please tell me what to count till?
1000
Please tell me what to count from?
My Apologies, but starting point value must be smaller than ending point value!
Please tell me what to count from?
Why is it going straight to the second written else statement?
Why is it skipping user entry for newInitialValue?
Please note that if edit code after ending value block to below after entering a string for newEndingValue and then correctly enter a number, this rids me of my error but generates another one if ran again and the user cooperates:
...
newInitialValue = input.nextInt(); //essentially gets skipped over by compiler only when previous catch statement is triggered
System.out.println("Please tell me what to count from?");
if(increasingOrDecreasing.equalsIgnoreCase("Increasing")|| increasingOrDecreasing.equals("++") || increasingOrDecreasing.equals("+"))
{...
additionally since its printing out "but starting point value must be smaller than ending point value" we can deduce its working with if(incre...) loop and the do and try loops respectively. But its skipping the (newI... = input...) and the if(newIntia...) lines of code. i know this cause even manually entering in newInitialValue = 2 (within paramenter) it still goes to this else clause.
-_- So the issue is within the while statements:
while(!input.hasNextint())
this looks ahead and checks the next user input, but since the catch consumed one it looks to the next next and it gets murky... essentially if i don't use this it works.
instead i used:
while(isError == true)
and under the do loop with the nested if statement i have:
if(blah blah blah){
isError=false;
break;
and before the next loop block i simply override the isError
isError=true;
//next block of code
The problem here is that you say to java do something if value 1 is true or value2 is true or value3 is true,and then you say on the else to do the same if using or.You got to understand that you need to use and && in order to help java to understand the else parameter.
My code below is looping twice. The 1st while loop before it asks for user input (to make a choice). I made it simpler by putting choice default is "N".
So it hits the if statement and begins the 2nd while loop. Now it asks the user for another choice. The user can only enter "A" as anything else will error trap. The user enters "A" and gets prompted to add a number (the variable num = 0). User enters a number.
The if statement closes, and the 2nd while loop comes back to the top, only it doesn't stop when the user is asked for a choice. Instead, it continues through the loop, hits the else statement, then comes back to the top of the 2nd while loop again and presents the user with a prompt for a choice.
Code Updated with More Information
while (true) { // 1st while loop
choice="N";
if (choice.equalsIgnoreCase("N")) {
while (true) { // 2nd while loop
System.out.println("|-|-| Add Number [A] Go Back [B]");
System.out.println("NUMBER: "+num);
System.out.print("Choice: ");
choice = c.nextLine();
if (choice.equalsIgnoreCase("A")){
System.out.print("Add: ");
num = (c.nextInt() + num);
System.out.println("");
}
else if (choice.equalsIgnoreCase("B")){
break;
}
else {
System.out.println("ERROR 19: Invalid response");
System.out.println("");
}
}
}
}
I have tried using different variables for choice. It did not work. I think I may need to try catch just below the 2nd while loop (before the user is prompted for a number), but that's only a idea. My question would be, why is this happening? And if possible, how can I fix it?
In your code while(true) will keep looping indefinitely. Either change the condition from always true to something which is conditionally true (using an if condition inside the while loop or a for loop). Or use a mix of break, return and continue when you think looping should stop.
Add a break statement in both if and else statement :
if (choice.equalsIgnoreCase("A")){
System.out.print("Add: ");
num = (c.nextInt() + num);
System.out.println("");
break;
}
else {
System.out.println("ERROR 19: Invalid response");
System.out.println("");
break;
}
I think you should change your loop. I suggest loop with like this :
boolean finished = false;
while(!finished) {
...
choice = c.nextLine();
if (choice.equalsIgnoreCase("A")){
System.out.print("Add: ");
num = (c.nextInt() + num);
System.out.println("");
} else if (choice.equalsIgnoreCase("Exit")) { //You can change this whatever you want
finished = true;
} else if (...){
... //another choice
}
else {
System.out.println("ERROR 19: Invalid response");
System.out.println("");
}
}
The Scanner#nextLine consumes the full line (hence "next line") of the user input. That's why you never get a repeated loop while using nextLine. The Scanner#nextInt does not, and the last newline character is consumed the next time Scanner#nextInt is called.
To answer my question:
if (choice.equalsIgnoreCase("A")){
System.out.print("Add: ");
num = (c.nextInt() + num); //Prompts user for input (number)
c.nextLine(); // Consumes the last newline character
System.out.println("");
}
else if (choice.equalsIgnoreCase("B")){
break;
}
else {
System.out.println("ERROR 19: Invalid response");
System.out.println("");
int option = input.nextInt();
input.nextLine(); // Consume newline left-over
String str1 = input.nextLine();
As answered from here: Scanner is skipping nextLine() after using next(), nextInt() or other nextFoo() methods
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();
I am writing a program that accepts two ints within the program using nextInt(); and have it wrapped in a try catch block to stop bad inputs such as doubles or chars.
When multiple wrong inputs are entered the loop repeats that same number of times. I assume this is because my scan.next() has to loop around enough times to catch the bad inputs w/o error. Is there a way to know this number on the first run through to make a loop to run next in that many times?
In the output the
if(cont == 'N') System.out.print("\nPlease re-enter\n\t:"); will output and mirror the amount of times a mismatched input was written. That is, if I input 3 3.3 it will repeat one extra time, if input s 3.3 2.5 it will repeat three extra times.
I tried putting a loop around scan.next() to default it to ten times, but was overboard and I had to input an extra 8 characters before it started reading again. Maybe a while loop but what would its condition be, I tried while(scan.next() != null){} but that condition never stopped.
//input error checking
char cont = 'Y';
do{
if(cont == 'N')
System.out.print("\nPlease re-enter\n\t:");
cont = 'Y';
/* to stop the accidential typing of things other
* than integers from being accepted
*/
try{
n1 = scan.nextInt();
n2 = scan.nextInt();
}catch(Exception e){
cont = 'N'; //bad input repeat loop
scan.next();//stops infinite loop by requesting Scanner try again
}
} while(cont == 'N');//do loop while told N for continue
Not sure what you want your code to do. From reading what you have posted I assume you want the user to input 2 ints and if he/she doesn't you want to prompt him/her to re-enter something until he/she inputs 2 ints.
If this is the case I would just add
scan = new Scanner(br.readLine());
after this if statement:
if(cont == 'N')
{System.out.print("\nPlease re-enter\n\t:");}
This will solve your looping issue
First try :
change the line in the exception catch from
scan.next();
to
while(scan.hasNext()){
scan.next();
}
You can try to do the following in your catch block:
while(scan.hasNext())
scan.next();
make it a method and do it with that method.
sth like this:
// do it until getting two Integers
boolean isItInteger = false;
while (isItInteger == false) {
isItInteger = getInt();
}
.
.
.
// your method for getting two Integers
public static boolean getInt() {
try {
Scanner sc = new Scanner(System.in);
n1 = sc.nextInt();
n2 = sc.nextInt();
} catch (Exception e) {
System.out.println("Please re-enter");
return false;
}
return true;
}