我需要用C语言创建一个基本的日期计算器,让用户输入YYYY-MM-DD格式的日期。我把它的基本知识写下来了。虽然我不需要这样做,但我想要多做一点,并考虑到闰年的因素。该程序运行良好;但是,它不能正确地计算闰年。当我输入日期2016-02-26时,我应该得到一个预期的结果2016-03-04,但我得到的结果是2016-03-03。我估计,如果我使用if else语句,效果就像下面使用模数一样。
if (month == 2 && year % 4) days = 29;
else days = 28;这是我的完整代码..。
//Does not require <stdlib.h>
#include <stdio.h>
// Set variables
int newDay, newMonth, newYear, daysInMonth, daysRemain;
// Set structure for day month year
struct date {
int day, month, year;
};
// set structure for date
struct date d1;
int main (void) {
//Intro
printf("Date calculation program by Keith A. Russell");
//Asks for user input
printf("\n\nPlease enter the year in four digit format (YYYY) ");
scanf("%i", &d1.year);
printf("\nEnter the month in two digit format (MM) ");
scanf("%i", &d1.month);
printf("\nEnter the day in two digit format (DD) ");
scanf("%i", &d1.day);
//Runs calculations to increase the date by a week
newDay = d1.day + 7;
newMonth = d1.month;
newYear = d1.year;
daysRemain = 0;
//For if the next week is going to be greater than the next month
if (newDay > 28)
checkMonth(); //Runs checkMonth Function
//Prints the dates
printf("\nThe new date is %i-%i-%i: \n", newYear, newMonth, newDay);
}
checkMonth() {
if (d1.month == 1 || 3 || 5 || 7 || 8 || 10 || 12)
daysInMonth = 31; //For months with 31 days
if (d1.month == 2 && d1.year % 4) //Attempt to calculate leap year
daysInMonth = 29;
else {
daysInMonth = 28; //All other years
}
if (d1.month == 4 || 6 || 9 || 11) //For months with 30 days
daysInMonth = 30;
//Sets up to advance the year if approaching the end of year
if (newDay > daysInMonth) {
daysRemain = newDay - daysInMonth;
newDay = daysRemain;
newMonth++;
checkYear();
}
}
//Runs function to advance to the next year
checkYear() {
if (d1.month == 12)
if (daysRemain > 0) {
newYear++;
newMonth = 1;
}
}如果有更好的方法来计算闰年,并将其包含在这个程序中,我将非常感谢。谢谢。
发布于 2017-06-13 00:05:57
首先,这是错误的
if (d1.month == 1 || 3 || 5 || 7 || 8 || 10 || 12)这将永远是正确的。你需要
if (d1.month == 1 || d1.month == 3 || d1.month == 5 ....)发布于 2017-06-13 00:10:34
这并不是你所想的那样:
if (d1.month == 1 || 3 || 5 || 7 || 8 || 10 || 12)您不能像这样将一个值与一系列值进行比较。你实际做的是这样的:
if ((d1.month == 1) || 3 || 5 || 7 || 8 || 10 || 12)您正在将d1.month与值1进行比较,然后将该布尔结果与其他几个数字进行逻辑或。由于所有这些数字都不为零,因此此表达式的计算结果始终为true。
这一点也是如此:
if (d1.month == 4 || 6 || 9 || 11)您需要显式地比较每个值:
if ((d1.month == 1) || (d1.month == 3) || (d1.month == 5) ...实际上,您可以使用带有fallthrough cases的switch更干净利落地完成此操作:
switch (d1.month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
daysInMonth = 31;
break;
case 4:
case 6:
case 9:
case 11:
daysInMonth = 30;
break;
case 2:
// years divisible by 100 are not leap years, unless they are also divisible by 400
daysInMonth = (d1.year % 400 == 0) ? 29 :
(d1.year % 100 == 0) ? 28 :
(d1.year % 4 == 0) ? 29 : 28;
break;
}发布于 2017-06-13 04:42:51
您的代码中存在多个问题:
(d1.month == 2 && d1.year % 4)表示1901年和2099年之间的正常年份,这不是闰年。正确的测试是这样的:if (d1.month == 2 && (d1.year % 4) == 0) //尝试计算闰年daysInMonth = 29;
但是请注意,根据公历改革后的历法,100的年份的倍数如果不是400的倍数也不是闰年,那么完整的测试是这样的:
如果(d1.month == 2) { daysInMonth = (d1.year %4 || (!(d1.year % 100) && (d1.year % 400))?28 : 29;}
if (d1.month == 1 || 3 || 5 || 7 || 8 || 10 || 12),您应该这样写:if (d1.month == 1 || d1.month == 3 || d1.month == 5 || d1.month == 7 || d1.month == 8 || d1.month == 10 || d1.month == 12)
要使代码更具可读性,可以使用switch语句。如果您首先检查d1.month在1到12之间,则可以将上述测试压缩为更紧凑的单个测试:
if ((1 << d1.month) & ((1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 8) | (1 << 10) | (1 << 12))) {
daysInMonth = 31;
}https://stackoverflow.com/questions/44503883
复制相似问题