Unable to exit loop with Sentinal value - java

I have been trying to exit the loop by using various methods, This is the closest I've gotten but still it has a Scanner mismatch error.
Could someone point out what im missing?
Code:
import java.util.*;
public class LeapYear
{
public static void main(String[] args) {
Scanner input=new Scanner(System.in);
boolean four ;
boolean hundred;
boolean four_hundred;
boolean quit=true;
int check= 2000;
int min=1582;
String test;
//System.out.println("Enter a year to check if it is a leap year");
do {
do {
System.out.println("Enter a year to check if it is a leap year");
if(check <min ) {
System.out.println("That year is too old, choose a year in more recent history");
}
check =input.nextInt();
} while( check < min);
// check =input.nextInt();
if(check % 4==0) {
four=true;
} else {
four=false;
}
if(check%100==0) {
hundred=true;
} else {
hundred=false;
}
if(check %400==0) {
four_hundred=true;
} else {
four_hundred=false;
}
if(four==true) {
if(four==true&&hundred==false&&four_hundred==false) {
System.out.println("The year is a leap year");
}
if(four==true&&hundred==true&&four_hundred==false) {
System.out.println("The year is not a leap year");
}
if(four==true&&hundred==true&&four_hundred==true) {
System.out.println("The year is a leap year");
}
} else {
System.out.println("The year is not a leap year");
}
System.out.println("DO YOU WANT TO QUIT: Y/N ?");
while(!input.hasNext("true|false")) {
System.out.println("That is neither a true or false.");
input.nextBoolean();
if(input.hasNextBoolean()) {
quit=true;
}
if(input.hasNextBoolean()) {
quit=false;
}
}
} while(!quit==false);
}
}

You could make the outer loop a while true loop. Then, when you want to quit, you just return from the method, therefore stopping the method & loop. No need for the quit sentinel value
You also prompt for Y/N, so you should check for that, not true or false.
String q = "n";
do {
System.out.println("Do you want to quit: Y/N ?");
String q = input.next();
if (q.equalsIgnoreCase("y")) return; // quit right here
else if (!q.equalsIgnoreCase("n"))
{
System.out.println("That is neither a y or n.");
continue; // repeat
} else { } // entered y, so continue on with the outer loop
} while (!q.equalsIgnoreCase("y") || !q.equalsIgnoreCase("n"));
And general tip. Writing this pattern is a very beginner thing to do, and it may look nice and easy to understand
if(check %400==0) {
four_hundred=true;
} else {
four_hundred=false;
}
But, you really should just write like so
four_hundred = check % 400;
and here, why get four is true inside the condition where you are guaranteed its value?
if(four==true) {
if(four==true&&hundred==false&&four_hundred==false) {
System.out.println("The year is a leap year");
}
if(four==true&&...

There are a few issues in your code that would explain why you cannot exit the loop.
System.out.println("DO YOU WANT TO QUIT: Y/N ?");
while(!input.hasNext("true|false")) {
System.out.println("That is neither a true or false.");
input.nextBoolean();
if(input.hasNextBoolean()) {
quit=true;
}
if(input.hasNextBoolean()) {
quit=false;
}
}
With input.nextBoolean(); you read the input but there are two issues:
an InputMismatchException will be thrown if the input cannot be scanned into true or false
you consume the input but do not put it into a variable
Ignoring the first issue for the moment, the problem is that then try to set quit based on another check of the input. This means that input.hasNextBoolean() can only be true if the user enters true or false one more time.
Aside from this while loop, there is also a problem with the outer most do/while
...
} while(!quit==false);
You are testing not quit and stay in the loop if it is false. This means that when quit == true you stay in the loop.
You probably want to write while (!quit).

I would suggest to improve your code:
Improve a names of variables.
Remove unused variables.
Simplify if statement expressions.
Here is a code:
import java.util.*;
public class LeapYear
{
public static void main( String[] args ) {
Scanner input = new Scanner(System.in);
boolean isFour;
boolean isQuit = true;
int checkedYear = 2000;
int minimumAcceptedYear = 1582;
//System.out.println("Enter a year to check if it is a leap year");
do {
do {
System.out.println("Enter a year to check if it is a leap year");
checkedYear = input.nextInt();
if ( checkedYear < minimumAcceptedYear ) {
System.out.println("That year is too old, choose a year in more recent history");
}
} while ( checkedYear < minimumAcceptedYear );
isFour = (checkedYear % 4) == 0;
if ( isFour ) {
System.out.println("The year is a leap year");
} else {
System.out.println("The year is not a leap year");
}
System.out.println("DO YOU WANT TO QUIT: (true/false) ?");
if ( input.hasNextBoolean() ) {
isQuit = input.nextBoolean();
} else {
System.out.println("That is neither a true or false.");
}
} while ( !isQuit );
}
}
This is looks a far better. I would you suggest extract
isFour = (checkedYear % 4) == 0;
if ( isFour ) {
System.out.println("The year is a leap year");
} else {
System.out.println("The year is not a leap year");
}
to another method isLeapYear with parameter aYear. You has a mismatch error because of you was giving invalid input data after checking is given year too old. You should move if condition below checkedYear assigment to avoid these error. I hope that's helpful answer.

Related

How should I structure this while loop? (JAVA)

New to Java. How should I structure this while loop to re-enter the loop when user input is 'Y'? Should the while go at the very beginning? The sample of the output is below code.
import java.util.Scanner;
public class RamosSLE33 {
public static void main(String[] args) {
char cont = 'Y';
String anniversaryGift = " ";
int year = 0;
Scanner input = new Scanner(System.in);
System.out.printf("ANNIVERSARY YEAR%n%n1. 50%n2. 55%n3. 60%n4. None of the above."
+ "%n%nSelect the anniversary year: ");
year = input.nextInt();
if (year == 1)
System.out.printf("The anniversary gift is gold.");
if (year == 2)
System.out.printf("The anniversary gift is emerald.");
if (year == 3)
System.out.printf("The anniversary gift is diamond.");
if (year == 4)
System.out.printf("Go to www.bernardine.com/jewelry-anniv.htm#traditional for more gift choices.");
cont = 'N';
while(Character.toUpperCase(cont) == 'Y') {
System.out.printf("%nSearch for another anniversary gift? Enter 'Y' or 'N': ");
cont = input.nextLine().charAt(0);
} // End while == Y
} //End main()
} //End class RamosSLE33
SAMPLE OUTPUT
You have few mistakes in the program.
Your while loop doesn't repetitively run the entire program
The Scanner input might be a Resource leak hence you have not closed it.
Please refer to the corrected program as below
public class RamosSLE33 {
public static void main(String[] args) {
char cont = 'Y';
int year = 0;
Scanner input = new Scanner(System.in);
while (Character.toUpperCase(cont) == 'Y') {
System.out.printf("ANNIVERSARY YEAR%n%n1. 50%n2. 55%n3. 60%n4. None of the above."
+ "%n%nSelect the anniversary year: ");
year = input.nextInt();
if (year == 1) {
System.out.printf("The anniversary gift is gold.");
} else if (year == 2) {
System.out.printf("The anniversary gift is emerald.");
} else if (year == 3) {
System.out.printf("The anniversary gift is diamond.");
} else if (year == 4) {
System.out.printf("Go to www.bernardine.com/jewelry-anniv.htm#traditional for more gift choices.");
} else {
System.out.printf("An invalid Input Number");
}
cont = 'N';
System.out.printf("%nSearch for another anniversary gift? Enter 'Y' or 'N': ");
cont = input.next(".").charAt(0);
} // End while == Y
input.close();
System.out.printf("%n The progrm ends: ");
} // End main()
}
Not sure if you shortcutted copying the code, but the shorthand ifs only do one line you'd need braces{} for 2.
this part
if (year == 4)
System.out.printf("Go to www.bernardine.com/jewelry-anniv.htm#traditional for more gift choices.");
cont = 'N';
Hence cont always equals 'N' before that loop, so it's never entered. That's probably what's getting you, rest is just me doing light code critiquing really.
You may also consider 'Y'.equals(cont.touppercase()) to avoid nullpointer exceptions when cont is null, though I think your Character factory might dodge that it's a good habit to do constants first.
maybe also using a do while instead so it always enters the thing to grab the input.nextline() before evaluating if it's Y and deciding to continue.
If you want it to reenter the whole method at the end look into recursion. You may need to make the cont variable class level or break it out into another method with cont as an argument; remember to have an exit condition if you go that route.

Q : Not understanding loop process? or possible if statements?

I am working on a project that involves creating a rental car calculator.
What I am trying to do is make it to where when asked: "What vehicle would you like to rent??". If a number that is not between 1-3 is entered when the user is prompted this, then I want the program to loop back to the point of being asked vehicle type again.
Similarly, when prompted for 'Please enter the number of days rented. (Example; 3) : ' I want to only allow the user to input whole positive numbers. for instance, not allowing input of 3.1, 2.35, 0.35 -2 and, etc...
here is what I have written and my attempt at these questions :
package inter;
import java.util.Scanner;
public class Inter {
public static void main(String []args){
int count=0;
int days;
double DailyFee=0, NontaxTotal, CarType, Total,FullTotal=0;
Scanner in=new Scanner(System.in);
System.out.println("If there are any customer press 1 else press 0");
int cus=in.nextInt();
while(cus!=0){
count++;
System.out.print("What vehical would you like to rent?\n");
System.out.println("Enter 1 for an economy car\n");
System.out.println("Enter 2 for a sedan car\n");
System.out.println("Enter 3 for an SUV");
CarType = in.nextInt();
if (CarType == 1) {
DailyFee=31.76;
}
else if(CarType == 2) {
DailyFee=40.32;
}
else if(CarType == 3) {
DailyFee=47.56;
}
else if(CarType <= 0) {
System.out.println("input is not a positive Integer ");
System.out.println("Please enter a positive integer value: ");
cus = 0; }
else if(CarType > 4) {
System.out.println("input is not a positive Integer ");
System.out.println("Please enter a positive integer value: ");
cus = 0; }
System.out.print("Please enter the number of days rented. (Example; 3) : ");
days = Integer.valueOf(in.nextLine());
double x=days;
NontaxTotal = (DailyFee * x);
Total = (NontaxTotal * 1.06);
FullTotal+=Total;
System.out.printf("The total amount due is $ %.2f \n",Total);
System.out.println("If there are any customer press 1 else press 0");
cus=in.nextInt();
}
System.out.println("Count of customers : "+count);
System.out.printf("Total of the Day : $ %.2f",FullTotal);
}
}
Let me help you with this,
I made this code for you, i tried it and it worked
this will check if both answers were whole numbers (integers) and more than zero and will also check if the answer was numeric in the first place so that if the user answered with letters he will be prompted to try again
This is my suggestion:
basically i used the try-catch block with InputMismatchException to detect if the answer was not an integer (whole number ) or was not numeric at all, every time a mistake is detected i flip a boolean to false and keep looping as long as this boolean is false (i flip the boolean back to true before checking otherwise once the user gives a wrong answer he will always be prompted to answer even if he gave a correct answer after)
int vehicleType;
int numberOfDays;
double dailyFee;
boolean validAnswer1 = false;
boolean validAnswer2 = false;
Scanner scan = new Scanner(System.in);
while (validAnswer1 == false) {
validAnswer1 = true;
System.out.println("Choose Vehicle Type");
try {
vehicleType = scan.nextInt();
if (vehicleType <= 0) {
System.out.println("Number must be more than zero");
validAnswer1 = false;
} else if (vehicleType >= 4) {
System.out.println("Number should be from 1 to 3");
validAnswer1 = false;
} else {
if (vehicleType == 1) {
dailyFee=31.76;
} else if(vehicleType == 2) {
dailyFee=40.32;
}else if(vehicleType == 3) {
dailyFee=47.56;
}
while (validAnswer2 == false) {
validAnswer2 = true;
try {
System.out.println("Enter number of days rented ?");
numberOfDays = scan.nextInt();
if (numberOfDays <= 0) {
System.out.println("Number of days must be more than zero");
validAnswer2 = false;
} else {
// calculate your rent total here
}
} catch(InputMismatchException ex) {
System.out.println("Answer must be an Integer");
validAnswer2 = false;
scan.next();
}
}
}
} catch (InputMismatchException ex) {
validAnswer1 = false;
System.out.println("Answer must be an Integer");
scan.next();
}
}
Hope this was useful, do let me know if you still need help

MasterMind-Resource Leak?

My code is running fine, but every line where I use a scanner it warns me that there is a "Resource leak; 'userGuess' is never closed" I don't understand what it means and could use some help solving it. Also if there is anything else in my code worth fixing I could use the help. Be warned I have a limited knowledge of Java programming. I also cannot get my TryCounter++ to work...
package masterMind2_1;
import java.util.Scanner;
public class MasterMind2_1 {
public static void main(String[] args) {
System.out.println("This is MasterMind, a logic game");
System.out.println("To win you must guess correctly where each number is(The Numbers Range from 1-4)");
System.out.println("You will be told if you get one correct");
System.out.println("You will only get 10 tries, then you lose");
System.out.println("Lets begin");
//Declare Array
int [] answerArray;
answerArray= new int [4];
//Initialize Array
//Change these value to change the answers needed to win
answerArray[0]=2;
answerArray[1]=3;
answerArray[2]=2;
answerArray[3]=2;
// //Create Board
// System.out.println("-- -- -- --");
boolean guessedAll = false;
int guessedCount=0;
int tryCounter=0;
while(tryCounter<9 || !guessedAll){
System.out.println("What is the first Number?");
Scanner userGuess = new Scanner(System.in);
int num = userGuess.nextInt();
if (num==answerArray[0]) {
guessedCount++;
}
System.out.println("What is the Second Number?");
Scanner userGuess1 = new Scanner(System.in);
int num1 = userGuess1.nextInt();
if (num1==answerArray[1]) {
guessedCount++;
}
System.out.println("What is the Third Number?");
Scanner userGuess2 = new Scanner(System.in);
int num2 = userGuess2.nextInt();
if (num2==answerArray[2]) {
guessedCount++;
}
System.out.println("What is the Fourth Number?");
Scanner userGuess3 = new Scanner(System.in);
int num3 = userGuess3.nextInt();
if (num3==answerArray[3]) {
guessedCount++;
}
System.out.println("Your guess was "+ num+" "+num1+" "+num2+" "+num3);
if (num==answerArray[0]) {
System.out.println("First number was correct");
} else {
System.out.println("First number was incorrect");
}
if (num1==answerArray[1]) {
System.out.println("Second number was correct");
} else {
System.out.println("Second number was incorrect");
}
if (num2==answerArray[2]) {
System.out.println("Third number was correct");
} else {
System.out.println("Third number was incorrect");
}
if (num3==answerArray[3]) {
System.out.println("Fourth number was correct");
} else {
System.out.println("Fourth number was incorrect");
}
if (guessedCount==4) {
System.out.println("YAY you won!!");
guessedAll=true;
tryCounter=10;
} else {
System.out.println("Try again, except this time don't fail!");
guessedAll=false;
tryCounter++;
guessedCount=0;
}
}//What if I collected all of the values first
} //then told them if they were right or Wrong?
//Black and White Pegs?
//Fix TryCounter...Why isn't it working
}
Thank you for the Help!
The error message is telling you that you never call the close() method on your Scanner object. A worse problem is that you create multiple Scanners when you only need one.
As for tryCounter not working...
while(tryCounter<9 || !guessedAll)
This will keep looping if either part of the condition is true. My guess is that !guessedAll is evaluating to true beyond 9 guesses, so your loop keeps running. You'll need to change the || to an && to get it stop looping after 9 tries. (Also, print out the values of your variables or use a debugger so you can verify that they are changing when you expect them to.)

Can you return a string from a while loop without using the return command?

I am learning java in the internet in sites like "oracle academy" and using Google to search how to do somethings, i wanted to make a simple java program that takes an number(day) a number or word(month) and another number(year), so if you input something like
"3" "1" and "1993"
it outputs
"January 1st, 1993"
and if you input something like
"2" "July" and "1992"
it outputs
"7/2/1992"
I kind of already know how to make it using "case" and while loops to tell you if you input something incorrectly, but on the "day" part i tried using a while loop to keep asking you to input something if the input wasn't a number between 1 and 31 but i can't make it return the number from the while loop using the return command, is there any way to return the number without using the return command or not?
the code:
public static void main(String[] args) {
String x;
Scanner scan = new Scanner(System.in);
//day
System.out.println("Insert Day");
while (1 < 2){
x = scan.nextLine();
if (x.matches(".*\\d.*")){
q = Integer.parseInt(x);
if ((0 < q) && (q < 32)){
return q;
}
else {
System.out.println("please use a valid number");
}
}
else {
System.out.println("please use a number");
}
}
System.out.println(q);
You can use return if you refactor this into a separate function:
public static int getDay() {
Scanner scan = new Scanner(System.in);
System.out.println("Insert Day");
while (true){
line = scan.nextLine();
if (line.matches(".*\\d.*")){
int day = Integer.parseInt(line);
if (0 < day && day < 32){
return day;
} else {
System.out.println("please use a valid number");
}
} else {
System.out.println("please use a number");
}
}
}
public static void main(String[] args) {
int day = getDay();
System.out.println(day);
}
Or you could use a break:
Scanner scan = new Scanner(System.in);
System.out.println("Insert Day");
int day = -1;
while (true){
line = scan.nextLine();
if (line.matches(".*\\d.*")){
day = Integer.parseInt(line);
if (0 < day && day < 32){
break;
} else {
System.out.println("please use a valid number");
}
} else {
System.out.println("please use a number");
}
}
Or you could use your while condition:
int day = -1;
Scanner scan = new Scanner(System.in);
System.out.println("Insert Day");
while (day < 1 || day > 31){
line = scan.nextLine();
if (line.matches(".*\\d.*")){
day = Integer.parseInt(line);
if (day < 1 || day > 31){
System.out.println("please use a valid number");
}
} else {
System.out.println("please use a number");
}
}
Also, you can simplify your code by using the NumberFormatException parseInt throws, instead of trying to validate it yourself with a regular expression:
int day = -1;
Scanner scan = new Scanner(System.in);
System.out.println("Insert Day");
while (day < 1 || day > 31){
line = scan.nextLine();
try {
day = Integer.parseInt(line);
if (day < 1 || day > 31){
System.out.println("please use a valid number");
}
} catch (NumberFormatException e) {
System.out.println("please use a number");
}
}
The return statement returns a value from the entire method you're in. But you're in main, which can't return a value (it's void).
If you want to end the while loop when you have a good value, then use the break statement to break out of the while loop. Control then passes to the next statement following the end of the loop.

Method in Java program won't pick up user input

The program I'm writing is to determine whether or not a year is a leap year. This is an assignment, so I am required to use the four methods I wrote inside the program. The program compiles and runs, it asks for user input at the appropriate places, but it doesn't take the input into the program. Also it's saying that the year is a leap year and looping no matter what has been inputted. I've very confused as to where there error is, since this program seems match the examples we were given.
import java.util.Scanner;
public class LeapYear {
public static void main(String[] args) {
boolean repeat;
String computeanother, yes="yes";
Scanner kb=new Scanner(System.in);
int year = -1;
boolean leap;
do
{
displayInstructions();
getYear(year);
leap = isLeap(year);
displayResults(year, leap);
System.out.println("Would you like to compute another year?");
computeanother = kb.nextLine();
if(computeanother.equals(yes))
repeat=true;
else
repeat=false;
} while(repeat=true);
}
public static void displayInstructions()
{
System.out.println("This program is designed to predict whether or not a year is a leap year.");
System.out.println("When prompted please enter a positive number for the year.");
System.out.println("Once the program has run completely, it will state the year and whether it is a leap year.");
}
public static void getYear(int year)
{
Scanner kb = new Scanner(System.in);
do {
System.out.println("Please enter the year.");
year=kb.nextInt();
} while (year < 0);
}
public static boolean isLeap(int year)
{
boolean leap;
if ((year%4==0 && year%100 != 0) || year%400==0){
leap = true;
return true;
} else {
leap = false;
return false;
}
}
public static void displayResults(int year, boolean leap)
{
if (leap = true) {
System.out.println("The year " +year);
System.out.println("is a leap year.");
} else {
System.out.println("The year " +year);
System.out.println("is not a leap year.");
}
}
}
Thanks for everyone's help! The edited code looks like this:
import java.util.Scanner;
public class LeapYear{
public static void main(String[] args){
boolean repeat;
String computeanother, yes="yes";
Scanner kb=new Scanner(System.in);
int year = -1;
boolean leap;
do
{
displayInstructions();
getYear(year);
leap = isLeap(year);
displayResults(year, leap);
System.out.println("Would you like to compute another year?");
computeanother = kb.nextLine();
repeat = computeanother.equals(yes);
}while(repeat);
}
public static void displayInstructions()
{
System.out.println("This program is designed to predict whether or not a year is a leap year.");
System.out.println("When prompted please enter a positive number for the year.");
System.out.println("Once the program has run completely, it will state the year and whether it is a leap year.");
}
public static int getYear(int year)
{
Scanner kb = new Scanner(System.in);
do{
System.out.println("Please enter the year.");
year=kb.nextInt();
}while (year < 0);
return year;
}
public static boolean isLeap(int year)
{
boolean leap;
year = getYear(year);
if ((year%4==0 && year%100 != 0) || year%400==0){
leap = true;
return true;}
else{
leap = false;
return false;}
}
public static int displayResults(int year, boolean leap)
{
year = getYear(year);
if (leap == true){
System.out.println("The year " +year);
System.out.println("is a leap year.");}
else{
System.out.println("The year " +year);
System.out.println("is not a leap year.");}
return year;
}
}
while(repeat=true);
In the while loop should be:
while(repeat == true);
or
while(repeat);
Aside from this being noted by everyone it can be noted you make this mistake twice:
if (leap = true) {
Should be:
if (leap == true) {
or
if (leap) {
You can also shorten your code:
do{
displayInstructions();
getYear(year);
leap = isLeap(year);
displayResults(year, leap);
System.out.println("Would you like to compute another year?");
computeanother = kb.nextLine();
repeat = computeanother.equals(yes) //this line makes code shorter
} while(repeat);
Indeed, always avoid code redundancy like this famous pattern:
if(expression) return true; else return false;
That becomes: return expression;
Change this:
while(repeat=true);
to
while(repeat==true);
or
while(repeat);
Here while(repeat=true); you are assigning a value, not comparing. while(repeat==true); or while(repeat); this will compare the value. It's always better to test like this while(repeat); instead of obvious while(repeat==true);. I hope it helps.
And you are not getting value for year as -1 because, you are returning from this method getYear(year); but ignoring the value. Change it to:
year = getYear(year);
This should work.

Categories