Gregorian Calendar in C - c

I really don't know much about c program so really need your help..
This is the program to find the day of input value(ex. 1583.3.31 -> Thursday) and print "Wrong year/month/day" if it is unvalid date.
I wrote return 0; in the middle part because I have to get out from this when the date is unvalid. I checked it works. But eventhough when the date is valid (ex. 1583.3.31) it doesn't go to the next part(should print day if number is valid) It just ends the program. I wonder why:(
#include <stdio.h>
int main(void) {
int year, month, day;
printf("Enter Gregorian year (year >= 1583): ");
scanf("%d", &year);
printf("Enter Gregorian month (month: 1..12): ");
scanf("%d", &month);
printf("Enter Gregorian day (1..28|29|30|31): ");
scanf("%d", &day);
{if (month < 1 || month > 12)
printf("Wrong month! Try again!");
if (year < 1583)
printf("Enter year >= 1583! Try again!");
if (day < 1 || day > 31)
printf("Wrong day! Try again!");
if (month == 4 && (day < 1 || day > 30))
printf("Wrong day! Try again!");
if (month == 6 && (day < 1 || day > 30))
printf("Wrong day! Try again!");
if (month == 9 && (day < 1 || day > 30))
printf("Wrong day! Try again!");
if (month == 11 && (day < 1 || day > 30))
printf("Wrong day! Try again!");
if (month == 2){
if (year % 4 == 0 && (day < 1 || day > 29))
printf("Wrong day! Try again!");
if (year % 100 == 0 && (day < 1 || day > 28))
printf("Wrong day! Try again!");
if (year % 400 == 0 && (day < 1 || day > 29))
printf("Wrong day! Try again!");}
else if (month == 2 && (day < 1 || day > 28))
printf("Wrong day! Try again!");
return 0;}
year += 8000;
if (month < 3) { year--; month += 12; }
long julian = (year*365) + (year/4) - (year/100) + (year/400) - 1200820 + (month*153+3)/5 - 92 + (day-1);
switch(julian % 7){
case 0:
printf("%d-%d-%d is Monday", year -= 8000, month, day);
break;
case 1:
printf("%d-%d-%d is Tuesday", year -= 8000, month, day);
break;
case 2:
printf("%d-%d-%d is Wednesday", year -= 8000, month, day);
break;
case 3:
printf("%d-%d-%d is Thursday", year -= 8000, month, day);
break;
case 4:
printf("%d-%d-%d is Friday", year -= 8000, month, day);
break;
case 5:
printf("%d-%d-%d is Saturday", year -= 8000, month, day);
break;
case 6:
printf("%d-%d-%d is Sunday", year -= 8000, month, day);
break;}
return 0;
}

You have an unconditional return 0; after the if statements. All but the first if should be an else if and the code for the correct date should be in an else block. Alternatively, return at the end of every error case, proceeding only if each check passes—although this will lead to a lot of duplication.
Enclosing all those statements in a single set of braces merely creates a lexical scope for variable declarations, probably not what you meant.
The code to check validity could instead be a do ... while loop that retries while you enter invalid dates, and you should calculate the day of the week after you fall through that loop, which will happen when the date is valid.

Related

How do I use switch case properly?

Can anyone tell me am I using switch cases correct? because when I input other number, it's output is always January.
#include <stdio.h>
int main()
{
int month, date, year;
printf("Enter Month Number: ");
scanf("%d", &month);
if (month > 12){
printf("Invalid Month! please choose a number below 12");
}
else{
printf("\nEnter Date Number: ");
scanf("%d", &date);
if (month = 1, 3, 5, 7, 8, 10, 12){
if (date > 31){
printf("\nInvalid Date! please choose a number below 31");
}
else{
printf("\nEnter Year: ");
scanf("%d", &year);
if (year > 9999){
printf("\nPlease make sure your year is correct!");
}
else if (year < 1000){
printf("\nPlease make sure your year is correct!");
}
else{
switch(month){
case 1:
printf("\nJanuary %d, %d", date, year);
break;
case 3:
printf("\nMarch %d, %d", date, year);
break;
case 5:
printf("\nMay %d, %d", date, year);
break;
case 7:
printf("\nJuly %d, %d", date, year);
break;
case 8:
printf("\nAug %d, %d", date, year);
break;
case 10:
printf("\nOctober %d, %d", date, year);
break;
case 12:
printf("\nDecember %d, %d", date, year);
break;
}
}
}
}
else if (month = 4, 6, 9, 11){
if (date > 30){
printf("\nInvalid Date! please choose a number below 30");
}
else{
printf("\nEnter Year: ");
scanf("%d", &year);
if (year > 9999){
printf("\nPlease make sure your year is correct!");
}
else if (year < 1000){
printf("\nPlease make sure your year is correct!");
}
else{
switch(month){
case 4:
printf("\nApril %d, %d", date, year);
break;
case 6:
printf("\nJne %d, %d", date, year);
break;
case 9:
printf("\nSeptember %d, %d", date, year);
break;
case 11:
printf("\nNovember %d, %d", date, year);
break;
}
}
}
}
else if (month = 2){
if (date > 29){
printf("\nInvalid Date! please choose a number below 29");
}
else{
printf("\nEnter Year: ");
scanf("%d", &year);
if (year > 9999){
printf("\nPlease make sure your year is correct!");
}
else if (year < 1000){
printf("\nPlease make sure your year is correct!");
}
else{
printf("\nFebruary %d, %d", date, year);
}
}
}
}
return 0;
}
A few issues ...
= is the assignment operator. You want the equality operator ==
if (month = 4, 6, 9, 11) is just incorrect syntax. As mentioned in the top comments, this would be done with a switch/case block or if ((month == 4) || (month == 6) || (month == 9) || (month == 11)).
The code is needlessly verbose. Having a struct that describes the month (days and month string) and an array of it greatly simplifies the code.
Prompting the user for all three values before doing checking can also simplify the code.
Here is a simplified version. It is annotated:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
struct month {
int days; // (max) number of days in month
const char *str; // month string
};
struct month months[12] = {
{ 31, "January" },
{ 29, "February" },
{ 31, "March" },
{ 30, "April" },
{ 31, "May" },
{ 30, "June" },
{ 31, "July" },
{ 31, "August" },
{ 30, "September" },
{ 31, "October" },
{ 30, "November" },
{ 31, "December" },
};
// asknum -- prompt user for number within a given range
int
asknum(const char *prompt,int lo,int hi)
{
char buf[100];
char *cp;
long val;
// prompt the user
printf("Enter %s (%d to %d): ",prompt,lo,hi);
fflush(stdout);
// get user's response -- exit on EOF
if (fgets(buf,sizeof(buf),stdin) == NULL)
exit(7);
// check for empty string
if (buf[0] == '\n') {
printf("No value specified\n");
exit(8);
}
// decode the value
errno = 0;
val = strtol(buf,&cp,10);
// check for error detected by strtol
if (errno != 0) {
printf("Invalid number\n");
exit(9);
}
// check for syntax error
if (*cp != '\n') {
printf("Invalid syntax\n");
exit(10);
}
// check range of number
if ((val < lo) || (val > hi)) {
printf("Number out of range -- must be between %d and %d\n",
lo,hi);
exit(11);
}
return val;
}
// isleap -- decide if it's a leap year
int
isleap(int year)
{
int leap = 0;
do {
if ((year % 4) != 0)
break;
if ((year % 400) == 0) {
leap = 1;
break;
}
if ((year % 100) == 0)
break;
leap = 1;
} while (0);
return leap;
}
int
main(void)
{
int month, date, year;
int days;
int leap = 0;
month = asknum("Month Number",1,12);
// locate the month descriptor
const struct month *mon = &months[month - 1];
date = asknum("Date Number",1,mon->days);
year = asknum("Year",1000,9999);
// get days in the month
days = mon->days;
// special case for february
if (month == 2) {
leap = isleap(year);
if (! leap)
days -= 1;
}
// check date against number of days in the month
if (date > days) {
printf("%s only has %d days\n",mon->str,days);
exit(2);
}
// print the date
printf("%s %d, %d\n",mon->str,date,year);
return 0;
}

How do I break loop in do while? [duplicate]

This question already has answers here:
Chaining multiple greater than/less than operators
(6 answers)
Closed last year.
How can I break the do while loop here in my code? The program should loop until the user inputs a valid year from the category.
When I enter the valid input, the printf still shows up even if it is meant to stop.
Here is the code below:
#include <stdio.h>
int main()
{
float year;
do {
printf("Please input your year of birth :");
scanf("%f", &year);
if ((year >= 1946) && (year <= 1964))
printf("You belong to the baby boomer generation \n");
else if ((year >= 1965) && (year <= 1980))
printf("You belong to the Generation X \n");
else if ((year >= 1981) && (year <= 1996))
printf("You belong to the Millenials/Generation Y \n");
else if ((year >= 1997) && (year <= 2012))
printf("You belong to the Zoomers/Generation Z \n");
} while(1946 > year < 2012);
}
(1946 > year < 2012)
should be
(year > 1946 && year < 2012)
and break; should be used if you want to break it somewhere like
if(year == 2000)
break;
Your while condition does not work as you expect. For the computer, 1946 > year < 2012 is (1946 > year) < 2021; 1946 > year will be either 0 or 1, so in the end you have 0 < 2021 (or 1 < 2021), which is always true, and the loop won't stop.
Try to change it to e.g. 1946 > year && year < 2012.
See https://stackoverflow.com/a/6961728/5471218 for details.
Add an else condition to break the loop.
if ((year >= 1946) && (year <= 1964))
printf("You belong to the baby boomer generation \n");
else if ((year >= 1965) && (year <= 1980))
printf("You belong to the Generation X \n");
else if ((year >= 1981) && (year <= 1996))
printf("You belong to the Millenials/Generation Y \n");
else if ((year >= 1997) && (year <= 2012))
printf("You belong to the Zoomers/Generation Z \n");
else
break;

12-month Calendar in C

I'm making a 12-month calendar in C. A program that displays twelve-month calendar for a particular year. The program prompts the user for the year to be printed, and figures out (a) whether the year is a leap-year and (b) what day of the week the chosen year starts on.
Instructions:
• main() prompts the user for input, calls a function of your own design to determine the starting day of the input year. It then invokes the function printCalendar() to actually print the twelve month calendar.
• printCalendar() takes two arguments, the year number and the starting day. It then loops through the year and calls the function printMonth() twelve times, once for each month.
• printMonth() takes three arguments, the year number, the month number and the starting day of that particular month, and it returns the number of the day on which the next month starts. Print month has to first call a function printMonthName() and then print out the days of the month in calendar format.
• printMonthName() takes the year number and the month number as arguments, prints out the line identifying the month, and returns the number of days in that month, taking into account leap year.
I followed those instructions and got this far:
#include <stdio.h>
#include <stdlib.h>
int daysInMonth;
int getDayCode(int year);
void printCalendar(int year, int dayCode);
int getYear(void);
int getYear(void){
int year;
printf("Please enter a year: ");
scanf("%i", &year);
printf("\n");
return year;
}
int getDayCode(int year){
int dayCode;
int x1, x2, x3;
x1 = (year - 1.)/ 4.0;
x2 = (year - 1.)/ 100.;
x3 = (year - 1.)/ 400.;
dayCode = (year + x1 - x2 + x3) %7;
return dayCode;
}
main(){
int year, dayCode;
year = getYear();
dayCode = getDayCode(year);
printCalendar(year, dayCode);
}
void printCalendar(int year, int dayCode){
int month;
printf(" %d Monthly Calendar\n", year);
printf(" \n");
printf(" \n");
for (month = 1; month <= 12; month++){
printMonth(year, month, dayCode);
}
}
int printMonthName(int year, int month){
switch (month){
case 1:
printf("\n\nJanuary %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 2:
printf("\n\nFebruary %i", year);
if (year%4 == 0 && year%100 != 0 || year%400 == 0){
//printf("This is a leap year.\n");
daysInMonth = 29;
return daysInMonth;
}
else{
//printf("This is not a leap year.\n");
daysInMonth = 28;
return daysInMonth;
}
break;
case 3:
printf("\n\nMarch %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 4:
printf("\n\nApril %i", year);
daysInMonth = 30;
return daysInMonth;
break;
case 5:
printf("\n\nMay %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 6:
printf("\n\nJune %i", year);
daysInMonth = 30;
return daysInMonth;
break;
case 7:
printf("\n\nJuly %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 8:
printf("\n\nAugust %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 9:
printf("\n\nSeptember %i", year);
daysInMonth = 30;
return daysInMonth;
break;
case 10:
printf("\n\nOctober %i", year);
daysInMonth = 31;
return daysInMonth;
break;
case 11:
printf("\n\nNovember %i", year);
daysInMonth = 30;
return daysInMonth;
break;
case 12:
printf("\n\nDecember %i", year);
daysInMonth = 31;
return daysInMonth;
break;
default:
printf("Invalid input! Please try again!\n");
break;
}
}
int printMonth(int year, int month, int dayCode){
int day;
printMonthName(year, month);
printf("\n\nSun Mon Tue Wed Thu Fri Sat\n" );
/* advance printer to correct position for first date */
for (day = 1; day <= 1 + dayCode * 5; day++)
printf(" ");
/* print the dates for one month */
for (day = 1; day <= daysInMonth; day++){
printf("%2d", day);
if ((day + dayCode) % 7 > 0) /* before Sat? */
/* move to next day in same week */
printf(" ");
else /* skip to next line to start with Sun */
printf("\n ");
}
/* set day_code for next month to begin */
dayCode = (dayCode + daysInMonth % 7);
return dayCode;
}
I put 2013 as input year, and my code starts January 1st on Tuesday, which is correct. But it is also starting on Tuesday for all 12 months, here is the problem:
Calendar Output 2013
Please help. I've been trying to get this to work for a long time now.
It looks as if you return dayCode in your printMonth function. However, you never do anything with that value in your printCalendar function. This is easily fixed by changing your for loop in printCalendar.
for (month = 1; month <= 12; month++){
dayCode = printMonth(year, month, dayCode);
}

What is wrong with my function that some sets of numbers worked and others don't?

I am supposed to take the users input and say if it's a valid date or not, but some dates print out it's valid or invalid then other times it just takes the input and the program ends with no output.
When user enters 15/11/11, it rearranges to 11/15/15. If the user enters
12/12/12, it works normally, but 04/16/16 just doesn't give any output.
Where is the problem in my function causing this issue?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//Declares function
int check_date(int month, int day, int year);
int main(void) {
int day, month, year;
//Asks user for input.
printf("Enter a date in this format : MM/DD/YY:");
//If user enters a wrong format it will be invalid.
if (scanf_s("%d/%d/%d", &month, &day, &year) == 3) {
check_date(day, month, year);
}
else {
printf("You entered a invalid date.\n");
}
system("pause");
return 0;
}
int check_date(int month, int day, int year) {
// If user inputs a valid date this will run.
if (month > 0 && month <= 12 && day > 0 && day <= 31 && year > 0 && year <= 99)
{
switch (month) {
//If users month input is 2(febuary) this case will run.
case 2:
//If it is a leap year and the day 29 is entered it is invalid.
if (year % 4 == 0) {
if (day == 29) {
printf("Invalid date.");
}
else {
printf("You entered a valid date, %d/%d/%d", month, day, year);
}
break;
//If user inputs 4 this case will run.
case 4:
//There is not 31 days in this month.
if (day == 31) {
printf("Invalid date.");
}
else {
printf("You entered a valid date, %d/%d/%d", month, day, year);
}
break;
//If user inputs 4 this case will run.
case 6:
//There is not 31 days in this month.
if (day == 31) {
printf("Invalid date.");
}
else {
printf("You entered a valid date, %d/%d/%d", month, day, year);
}
break;
//If user inputs 4 this case will run.
case 9:
//There is not 31 days in this month.
if (day == 31) {
printf("Invalid date.");
}
else {
printf("You entered a valid date, %d/%d/%d", month, day, year);
}
break;
//If user inputs 4 this case will run.
case 11:
//There is not 31 days in this month.
if (day == 31) {
printf("Invalid date.");
}
else {
printf("You entered a valid date, %d/%d/%d", month, day, year);
}
break;
//If user enters any other date other then the cases it is valid.
default:
printf("You entered a valid date, %d/%d/%d", month, day, year);
break;
}
//If user enters anything other then the correct format, this else will run.
else {
printf("You entered a invalid date.");
}
}
}
}
Try this code, is more simple
/*C program to validate date (Check date is valid or not).*/
#include <stdio.h>
int main()
{
int dd,mm,yy;
printf("Enter date (DD/MM/YYYY format): ");
scanf("%d/%d/%d",&dd,&mm,&yy);
//check year
if(yy>=1900 && yy<=9999)
{
//check month
if(mm>=1 && mm<=12)
{
//check days
if((dd>=1 && dd<=31) && (mm==1 || mm==3 || mm==5 || mm==7 || mm==8 || mm==10 || mm==12))
printf("Date is valid.\n");
else if((dd>=1 && dd<=30) && (mm==4 || mm==6 || mm==9 || mm==11))
printf("Date is valid.\n");
else if((dd>=1 && dd<=28) && (mm==2))
printf("Date is valid.\n");
else if(dd==29 && mm==2 && (yy%400==0 ||(yy%4==0 && yy%100!=0)))
printf("Date is valid.\n");
else
printf("Day is invalid.\n");
}
else
{
printf("Month is not valid.\n");
}
}
else
{
printf("Year is not valid.\n");
}
return 0;
}

Days between dates will not compile

I have been trying to get this to work. I need to input 2 dates (MM DD) and then have the program tell me the amount of days between the 2 dates. But for some reason when i try to use month 2 (February) I dont think its registering that I indicated it having only 28 days. Also when i enter the same date i cant get it to say "0". Please help thank you
#include <stdio.h>
#include <stdlib.h>
//constructs dates for calculation
struct date{
int month;
int day;
};//end date
int main()
{
struct date first, second; //creates 2 dates to calculate
int finalDays = 0;
int total = 0;
int i = 0;
int valid=0;
printf("Enter first date \n");
scanf("%d %d", &first.month, &first.day); //user input: first date
if (first.month == 1||3||5||7||8||10){
if(first.day > 31){
printf("Invalid Day\n");
valid += 1;
}
}
else if (first.month == 4||6||9||11 ){
if (first.day > 30){
printf("Invalid Day\n");
valid += 1;
}
}
else if (first.month == 2){
if(first.day > 28){
printf("Invalid Day");
valid += 1;
}
}
printf("Enter second date\n");
scanf("%d %d", &second.month, &second.day); // user input: second date
if (second.month == 1||3||5||7||8||10){
if(second.day > 31){
printf("Invalid Day\n");
valid += 1;
}
}
else if (second.month == 4||6||9||11 ){
if (second.day > 30){
printf("Invalid Day\n");
valid += 1;
}
}
else if (second.month ==2){
if(second.day > 28){
printf("Invalid Day");
valid += 1;
}
}
if (first.month == second.month && first.day == second.day){
printf("Days between dates: 0");
valid += 1;
}
//Prints statement if month is invalid
if(first.month > 12 || second.month > 12 || first.month<1 || second.month<1){
printf("Invalid Date: Invalid month");
}
//Prints statement if second date precedes first
if(second.month<first.month){
printf("Invalid. Second date cannot precede first date.");
}
if (second.month==first.month && second.day<first.day){
printf("Invalid. Second date cannot precede first date.");
}
if(first.month==second.month){
finalDays = (second.day - first.day);
printf("Days between dates: %d", finalDays);
valid+=1;
}
if(first.month == 1||3||5||7||8||10||12) // Days remaining in first month
total = 31 - first.day;
else if(first.month == 4||6||9||11)
total = 30 - first.day;
else if(first.month == 2)
total = 28 - first.day;
for(i = first.month + 1; i < second.month; i++)
{
if(i == 3||5||7||8||10||12)
total += 31;
else if(i == 4||6||9||11)
total += 30;
}
total += second.day;
if(valid == 0){
printf("First date: %d %d \n", first.month, first.day);
printf("Second date: %d %d \n", second.month, second.day);
printf("Days between dates: %d", total);
}
return 0;
} //end main
if (first.month == 1||3||5||7||8||10){
This won't do what you want it to do. It will be evaluated as (first.month == 1)||3||5||7||8||10, which will evaluate to true for all non-zero months.
This would be better written as a case statement;
switch (first.month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
/* Handle 31 day months */
...
break;
case 4:
case 6:
case 9:
case 11:
/* Handle 30 day months */
...
break;
case 2:
/* Handle February */
...
break;
default:
/* Handle invalid month */
break;
}

Resources