I am writing a program for class that is a leap year checker. I have the loop working from what I understand however it goes into an infinite loop still? Zero wont terminate the program. I've tried using else if, if, while, what have I done wrong? This is my third go at rewriting this and am completely lost now -_-. Any help or tips would be appreciated.
import java.util.Scanner;
public class LeapYearChecker {
public static void main(String[] args){
System.out.println("Please enter a date to find out if the year is a leap year.");
Scanner userInput = new Scanner(System.in);
int year = userInput.nextInt();
while(year == 0)
{
System.out.println();
}
if (year < 1582){
System.out.println("Please enter a date after 1582. The date you entered was" + year + ".");
}if((year % 4 == 0) && (year % 100 !=0) || (year % 400 == 0)){
System.out.println("That is a leap year");
}else{
System.out.println(year +" is not a leap year.");
}
}
}
while (year == 0)
{
System.out.println();
}
There's your problem, if the year is 0, your program will infinitely output a new line.
Furthermore, your ifs for checking if it is a leap year isn't inside the loop body, so even if you enter a non-zero number, the code will only run once.
Try the following code, be sure to read the comments to understand what's going on:
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
int year = -1; //Give your int a default value so the main loop will execute
while (year != 0) //-1 not equal to zero, so your code will start
{
System.out.print("Please enter a year: "); //Now we get the value of the year
year = in.nextInt(); //Put it into our variable
if (year < 1582) //And if it's less than 1582
{
if (year != 0)
System.out.println("Year must not be less than 1582!"); //Notify the user, unless they are exiting the program
continue; //restart the while loop, this is quite a useful statement!
}
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) //Check if it's a leap year
System.out.println("That is a leap year!\n");
else
System.out.println("That is not a leap year :(\n");
//End of the loop, so it goes back to the beginning, which asks the user again for the year
//So if you enter 0 next the program will close
}
}
The first loop is infinite. You forgot to read the user input inside.
Your loop will only run if a user enters 0. And once they do, your program will be stuck in an infinite loop since you haven't changed the value of year inside your while.
I'm assuming that you want to keep prompting the user to keep entering numbers until they enter 0? Then I would restructure your main method so that it surrounds the code where you retrieve and process input. Like so:
System.out.println("Please enter a date to find out if the year is a leap year.");
Scanner userInput = new Scanner(System.in);
int year;
do {
year = userInput.nextInt();
/**
* Print some message based input.
*/
} while (year != 0); // Loop until user enters 0
Related
I wrote a simple program that is supposed to display whether if a user inputted int is a leap year or not, and if so what leap year is it.
During running of the program whenever a number that was not supposed to be a leap year was inputted it did not print the else statement.
Note: This was written in the IDE BlueJ so io was automatically imported hence why I did not import it
/**
* Reads a user inputted integer value and determines if it is a leap year
* Created by Oh boy I suck at this
* 9 September 2019
*/
import java.util.Scanner;
public class LeapYear
{
public static int getYear(String prompt)
{
String newLine = System.getProperty("line.separator");
int value = 0;
boolean flag = true;
while (flag)
{
Scanner scan = new Scanner(System.in);
System.out.println(prompt + ": ");
try
{
value = scan.nextInt();
flag = false;
}
catch(java.util.InputMismatchException e)
{
System.out.println("What you have inputed was not an int.");
System.out.println(newLine);
}
}
return value;
}
public static void main (String[] args)
{
int year = getYear("Input the year ");
final int leapYear = year/4;
if(year % 4 == 0){
if(year % 100 >= 1){
if(year % 400 >= 1){
System.out.println("The year inputted: " + year + " is equivilant to " + leapYear + " leap year(s).");
}
else{
System.out.println("The year inputted: " + year + " is not a leap year.");
}
}
}
}
}
Let us look at your if statements, and remember the rules for leap years.
Understanding leap years
In general, a leap year is a year that is divisible by four, i.e. where the statement year % 4 == 0 is true.
But: If a year is not a leap year, when it is divisible by 100. I.e. year % 100 == 0 is true.
Exception: When that is also divisible by 400, i.e. year % 400 == 0 is true - then we have a leap year.
Basically: divisible by four yields a candidate - you then have to study it further to make a final decision.
Decision tree
Is it a leap year candidate? year % 4 == 0 Otherwise: Display "not a leap year"
Is it a leap year exception (every 100 years)? year % 100 == 0 Otherwise: Display "not a leap year"
Is it a leap year exception exception (every 400 years)? year % 400 == 0 True => Display "leap year", False => Display "not a leap year"
Your implementation
Let's first look at your if statement.
Your first if statement checks whether the year is divisible by four. This is so that you know whether you deal with a leap year candidate. So this is correct - but you forgot to deal with the case, when the year is NOT a leap year (so here you miss a possible "is not a leap year" output)
Now it gets a bit confusing. You check whether the year is NOT divisible by 100. If a leap year candidate is NOT divisible by 100 it IS a leap year. So you can output success, but you have to deal with the "else" case.
The third if is nested in the wrong if block. It belongs into the else block of the parent.
Hints
Try to get an understanding on how the input and the output relate to each other and try to hit every if / else.
Whenever you write an if think about whether you need the corresponding else block.
If things get weird, try to "trace" your program with "breadcrumb outputs": System.out.println("1"); System.out.println("2"); ... on every line where you deal with branching or looping (if,else,switch,while...) this will trace every step the program does on the command line. You can use this until your school encourages you to use a proper IDE.
Don't forget: Practice makes perfect ;)
Pseude code (spoiler)
Only use this if you're completely stuck.
if (year % 4 == 0) {
// this might be a leap year - we need to dig further
if (year % 100 == 0) {
if (year % 400 == 0) {
print "leap year"
} else {
print "not a leap year"
}
} else {
print "leap year"
}
} else {
print "not a leap year"
}
Bottom line
Some of your logic is incorrect and you forget to implement the else branches.
HTH
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.
This question already has answers here:
Java variable scope in if statement [duplicate]
(5 answers)
Closed 5 years ago.
I was attempting to code a program that gives you the season based on an inputed month and day, but ran into a problem halfway through. After I intialize the variable month in an if statement, to check if the value inputed is a valid month, I cannot use the variable month later in the code to find the season as it gives me the error "cannot find symbol." Any help would be much appreciated.
import java.util.Scanner;
public class Date
{
public static void main(String [] args)
{
Scanner in = new Scanner(System.in);
System.out.println("Please enter the number of the month: ");
if (in.hasNextInt() && in.nextInt() > 0 && in.nextInt() <= 12)
{
int month = in.nextInt();
}
else
{
System.out.println("Error: Invlaid month value");
}
System.out.println("Please enter the day: ");
int day = in.nextInt();
String season;
if (0 < month && month <= 3)
{
season = "Winter";
}
else if (3 < month && month <= 6)
{
season = "Spring";
}
else if (6 < month && month <= 9)
{
season = "Summer";
}
else if (9 < month && month <= 12)
{
season = "Fall";
}
}
}
The problem you encounter is that you have declared the variable within the if statement, meaning it may only be accessed within the { }. This article goes over the basics of variable scope in Java. You will only be able to access a variable from a scope if the variable was defined in a scope that is a subset of the current scope.
To achieve what you want, you will need to declare the variable outside the if-statement so that it can be accessible. Note you will need to handle the case when month is invalid otherwise you will have the default value of 0.
int month = 0;
if (in.hasNextInt()) {
month = in.nextInt();
if (!(month > 0 && month <= 12)) {
month = 0;
System.out.println("ERROR");
}
} else {
// Handle graceful exit
}
...
if (0 < month && month <= 3) { ... }
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.
Could someone tell me how to put an error message in to the following code? If the user enters a number that is not between 0 and 12, how do I output "Invalid entry".
The program at the moment works fine and if an invalid character is entered the user is allowed to try again.
int hours;
do {
System.out.print("Enter hours: ");
hours = myscanner.nextInt();
} while (hours < 0 || hours > 12);
I would use an "infinite" while loop and break out of it when the hours figure is valid. while(true) { ... } is idiomatic Java.
Scanner scanner = new Scanner(System.in);
int hours;
while (true) {
System.out.print("Enter hours: ");
hours = scanner.nextInt();
if (hours >= 0 && hours <= 12) {
break;
}
System.err.println("Invalid entry (should be 0-12)");
}
int hours;
boolean valid;
do {
System.out.print("Enter hours: ");
hours = myscanner.nextInt();
valid = (hours >= 0 && hours <= 12);
if (!valid)
System.out.println("Invalid entry");
} while (!valid);
NOTE: I've added a variable, because otherwise, you'd have duplicate condition there
NOTE2: I've also reverted the condition because I don't like if booleans are referring to negative condition(I prefer valid over invalid)
int hours;
do {
System.out.print("Enter hours: ");
hours = myscanner.nextInt();
if (hours < 0 || hours > 12) System.out.println("Please insert a valid entry");
} while (hours < 0 || hours > 12);