I'm making a program which calculates the date by giving the program a date and number of days to add to that date in input. In order to do this, I need to make a switch and make it repeat with a loop, but for some reasons, the program gets frozen and doesn't do anything after the user inserts the number of days to add. I've tried removing loop and the program works. Looking forward to someone who might help me fix this.
Here's the part of the code from getting number of days to add to the end of loop:
cin>>addDays;
while (addDays > 0) {
switch (month) {
//months with 31 days
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
{
finalDay = day addDays;
if (finalDay > 31) {
addDays = finalDay - 31;
month ;
day = 1;
}
break;
}
//months with 30 days
case 4:
case 6:
case 9:
case 11:
{
finalDay = day addDays;
if (finalDay > 30) {
addDays = finalDay - 30;
month ;
day = 1;
}
break;
}
//december
case 12:
{
finalDay = day addDays; //oggi è 10. Voglio aggiungere 30
if (finalDay > 31) { //40 è maggiore di 31
addDays = finalDay - 31; //l'aggiunta 30 diventa 40 - 31 che fa 9
year ;
day = 1;
month = 1;
}
break;
}
//february
case 2:
{
finalDay = day addDays;
if (year % 4 == 0) {
if (finalDay > 29) {
addDays = finalDay - 29;
month ;
day = 1;
}
}
else {
if (finalDay > 28) {
addDays = finalDay - 28;
month ;
day = 1;
}
}
break;
}
}
}
CodePudding user response:
Your loop runs until addDays
falls to <= 0
. The problem is, when you add addDays
to day
, if the resulting finalDay
IS within the current month
's number of days, you ARE NOT breaking the loop, and you ARE NOT adjusting the values of day
or addDays
either, so the loop iterates again with the same day
and addDays
values, calculating the same finalDay
value, over and over, endlessly. That is why your program appears frozen.
After fixing that, you are also not taking into account the possibility that addDays
might span more than a full month's worth of days. The user could ask to add more than 1 month at a time. So you need to adjust addDays
more granularly per month.
Also, when the current month
is 2
(February), your leap year calculation is incomplete. Being evenly divisible by 4
is not the only rule you need to check to know if the year
is a leap year. A year
that is evenly divisible by 4
and 100
but not evenly divisible by 400
is not a leap year.
With that said, try something more like this instead:
bool isLeapYear(int year)
{
return ((year % 4) == 0) &&
(((year % 100) != 0) || ((year % 400) == 0));
}
int lastDayInMonth(int year, int month)
{
switch (month) {
//months with 31 days
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
return 31;
//months with 30 days
case 4:
case 6:
case 9:
case 11:
return 30;
//month with 28 or 29 days
case 2:
return isLeapYear(year) ? 29 : 28;
}
return 0;
}
int year, month, day, addDays, lastDay;
...
cin >> addDays;
while (addDays > 0) {
lastDay = lastDayInMonth(year, month);
day = addDays;
if (day <= lastDay) break;
addDays -= (lastDay - day);
if ( month == 13) {
year;
month = 1;
}
day = 1;
}
That being said, have a look at this answer, which wraps up this kind of logic in a reusable struct
named Date
that has an overloaded operator =
for adding days.
CodePudding user response:
Thank you very much for your help! You made me understand where the mistake was. I've fixed it and it now works perfectly. But because I'm not as experienced as you and I was having difficulties to read that code, instead of doing as you did, I've added an else
to every if
inside the switch
, which resets addDays
to 0, because assignment statements copy their value, they don't move it, for some reasons I wasn't thinking about this stupid and basic thing.
And also thanks for letting me notice about the uncomplete leap year algorithm. Here's the fixed code. Have a good day!
cin>>addDays;
while (addDays > 0) {
switch (month) {
//months with 31 days
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
{
finalDay = day addDays;
if (finalDay > 31) {
addDays = finalDay - 31;
month ;
day = 0;
}
else {
addDays = 0;
}
break;
}
//months with 30 days
case 4:
case 6:
case 9:
case 11:
{
finalDay = day addDays;
if (finalDay > 30) {
addDays = finalDay - 30;
month ;
day = 0;
}
else {
addDays = 0;
}
break;
}
//december
case 12:
{
finalDay = day addDays; //oggi è 10. Voglio aggiungere 30
if (finalDay > 31) { //40 è maggiore di 31
addDays = finalDay - 31; //l'aggiunta 30 diventa 40 - 31 che fa 9
year ;
day = 0;
month = 1;
}
else {
addDays = 0;
}
break;
}
//february
case 2:
{
finalDay = day addDays;
if ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))) {
if (finalDay > 29) {
addDays = finalDay - 29;
month ;
day = 0;
}
else {
addDays = 0;
}
}
else {
if (finalDay > 28) {
addDays = finalDay - 28;
month ;
day = 0;
}
else {
addDays = 0;
}
}
break;
}
}
}