Having trouble with a function in C
-
In my program, I am asking the user to input a date(in just integers ie 12 31 2019 367) and the number of days they add to it. In one of my functions, this is precisely what I am doing. The user inputs 12 31 2019 367, and the program is meant to print 1 1 2021, but instead prints 1 1 2020(a year behind)... What I did(Sorry for a lot of code, I tried to keep it simple and clean): int days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; void add_days_to_date(int *mm, int *dd, int *yy, int days_left_to_add) { int days_left_in_month; while(days_left_in_month > 0) { days_left_in_month = days_in_month[*mm] - *dd; // days_left_in_month = days_in_month[*mm] - *dd; if (days_in_month[2] && is_leap_year(*yy) == true) { days_left_in_month++; } } // end while printf("after while\n"); if(days_left_to_add > days_left_in_month) { days_left_to_add -= days_left_in_month; *dd = 1; if(*mm == 12) { *mm = 1; (*yy)++; } else { (*mm)++; } } else { *dd += days_left_to_add; days_left_to_add = 0; } } int main() { int mm, dd, yy, days_left_to_add; printf("Please enter a date between the years 1800 and 10000 in the format mm dd yy and provide the number of days to add to this date:\n"); scanf("%d %d %d %d", &mm, &dd, &yy, &days_left_to_add); // printf("\nREAD\n"); //These are pointers, so they have to be at certain location i.e. int* mm = &mm add_days_to_date(&mm, &dd, &yy, days_left_to_add); printf("%d %d %d\n", mm, dd, yy); } What I got after inputs: Inputs: 12 31 2019 367 Output: 1 1 2020(meant to be 1 1 2021) Thank you in advance and for your time and patience...
-
In my program, I am asking the user to input a date(in just integers ie 12 31 2019 367) and the number of days they add to it. In one of my functions, this is precisely what I am doing. The user inputs 12 31 2019 367, and the program is meant to print 1 1 2021, but instead prints 1 1 2020(a year behind)... What I did(Sorry for a lot of code, I tried to keep it simple and clean): int days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; void add_days_to_date(int *mm, int *dd, int *yy, int days_left_to_add) { int days_left_in_month; while(days_left_in_month > 0) { days_left_in_month = days_in_month[*mm] - *dd; // days_left_in_month = days_in_month[*mm] - *dd; if (days_in_month[2] && is_leap_year(*yy) == true) { days_left_in_month++; } } // end while printf("after while\n"); if(days_left_to_add > days_left_in_month) { days_left_to_add -= days_left_in_month; *dd = 1; if(*mm == 12) { *mm = 1; (*yy)++; } else { (*mm)++; } } else { *dd += days_left_to_add; days_left_to_add = 0; } } int main() { int mm, dd, yy, days_left_to_add; printf("Please enter a date between the years 1800 and 10000 in the format mm dd yy and provide the number of days to add to this date:\n"); scanf("%d %d %d %d", &mm, &dd, &yy, &days_left_to_add); // printf("\nREAD\n"); //These are pointers, so they have to be at certain location i.e. int* mm = &mm add_days_to_date(&mm, &dd, &yy, days_left_to_add); printf("%d %d %d\n", mm, dd, yy); } What I got after inputs: Inputs: 12 31 2019 367 Output: 1 1 2020(meant to be 1 1 2021) Thank you in advance and for your time and patience...
You have to debug your code to see where, how and why it "calculates" wrong result!
-
In my program, I am asking the user to input a date(in just integers ie 12 31 2019 367) and the number of days they add to it. In one of my functions, this is precisely what I am doing. The user inputs 12 31 2019 367, and the program is meant to print 1 1 2021, but instead prints 1 1 2020(a year behind)... What I did(Sorry for a lot of code, I tried to keep it simple and clean): int days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; void add_days_to_date(int *mm, int *dd, int *yy, int days_left_to_add) { int days_left_in_month; while(days_left_in_month > 0) { days_left_in_month = days_in_month[*mm] - *dd; // days_left_in_month = days_in_month[*mm] - *dd; if (days_in_month[2] && is_leap_year(*yy) == true) { days_left_in_month++; } } // end while printf("after while\n"); if(days_left_to_add > days_left_in_month) { days_left_to_add -= days_left_in_month; *dd = 1; if(*mm == 12) { *mm = 1; (*yy)++; } else { (*mm)++; } } else { *dd += days_left_to_add; days_left_to_add = 0; } } int main() { int mm, dd, yy, days_left_to_add; printf("Please enter a date between the years 1800 and 10000 in the format mm dd yy and provide the number of days to add to this date:\n"); scanf("%d %d %d %d", &mm, &dd, &yy, &days_left_to_add); // printf("\nREAD\n"); //These are pointers, so they have to be at certain location i.e. int* mm = &mm add_days_to_date(&mm, &dd, &yy, days_left_to_add); printf("%d %d %d\n", mm, dd, yy); } What I got after inputs: Inputs: 12 31 2019 367 Output: 1 1 2020(meant to be 1 1 2021) Thank you in advance and for your time and patience...
Your code is somewhat confusing, but I did notice the following:
int days_left_in_month; // *** this needs to be initialised to some value
while(days_left_in_month > 0)
{
days_left_in_month = days_in_month[*mm] - *dd;
// days_left_in_month = days_in_month[*mm] - *dd;
if (days_in_month[2] && is_leap_year(*yy) == true) // ***days_in_month[2] is always non-zero, you should be checking if month is greater than 2.
{
days_left_in_month++;
}
} // end whileThe actual logic needed is as follows:
Set days_in_year to the actual number of days up to the date given, which in the case above should be 365.
Add days_to_add to days_in_year.
While days_in_year > 365
{
add 1 to year
subtract 365 from days_in_year
}
Use the remaining value of days_in_year to calculate the month and day.Obviously an adjustment for leap years will be needed somewhere in there.
-
In my program, I am asking the user to input a date(in just integers ie 12 31 2019 367) and the number of days they add to it. In one of my functions, this is precisely what I am doing. The user inputs 12 31 2019 367, and the program is meant to print 1 1 2021, but instead prints 1 1 2020(a year behind)... What I did(Sorry for a lot of code, I tried to keep it simple and clean): int days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; void add_days_to_date(int *mm, int *dd, int *yy, int days_left_to_add) { int days_left_in_month; while(days_left_in_month > 0) { days_left_in_month = days_in_month[*mm] - *dd; // days_left_in_month = days_in_month[*mm] - *dd; if (days_in_month[2] && is_leap_year(*yy) == true) { days_left_in_month++; } } // end while printf("after while\n"); if(days_left_to_add > days_left_in_month) { days_left_to_add -= days_left_in_month; *dd = 1; if(*mm == 12) { *mm = 1; (*yy)++; } else { (*mm)++; } } else { *dd += days_left_to_add; days_left_to_add = 0; } } int main() { int mm, dd, yy, days_left_to_add; printf("Please enter a date between the years 1800 and 10000 in the format mm dd yy and provide the number of days to add to this date:\n"); scanf("%d %d %d %d", &mm, &dd, &yy, &days_left_to_add); // printf("\nREAD\n"); //These are pointers, so they have to be at certain location i.e. int* mm = &mm add_days_to_date(&mm, &dd, &yy, days_left_to_add); printf("%d %d %d\n", mm, dd, yy); } What I got after inputs: Inputs: 12 31 2019 367 Output: 1 1 2020(meant to be 1 1 2021) Thank you in advance and for your time and patience...
As Victor was saying, this is the tough part of a programmer's job: finding the errors in your code. Most of the time you are on your own when doing it but in this case I'll try to do part of it with you hoping the experience will be useful. Before we start, when posting code here, try to paste it between the <pre></pre> tags. It makes it for a much nicer and easier to read code.
int days_in_month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
void add_days_to_date (int* mm, int* dd, int* yy, int days_left_to_add)
{
int days_left_in_month;
while (days_left_in_month > 0)Now, ask yourself, what is the value of
days_left_in_month
when the computer tries to evaluate the while loop for the first time? The answer is that it is not known. This is an "uninitialized local variable" bug and it is very common. The compiler has reserved space for the variable but its content can be anything. We have to fix this.while (days_left_in_month > 0)
{
days_left_in_month = days_in_month[*mm] - *dd;
if (days_in_month[2] && is_leap_year (*yy) == true)Oops, here is another bug: you wrote
days_in_month[2]
which is 28 and clearly not zero but what you probably had in mind was more like:if (month == 2 && is_leap_year(*yy) == true)
If we fix the two errors we found your code will be looking something like this:
void add_days_to_date (int* mm, int* dd, int* yy, int days_left_to_add)
{
int days_left_in_month;
days_left_in_month = days_in_month[*mm] - *dd;
if (*mm == 2 && is_leap_year (*yy))
days_left_in_month++;Now it's really the time to start a loop but this loop will have to run until the
days_left_to_add
is greater thandays_left_in_month
. Here I'll stop and let you finish the code. Post back the result and I'll give you more feedback on algorithm and style. EDIT - I see that while I was writing my long convoluting answer Richard had already made the same points in a more concise form :)Mircea
-
As Victor was saying, this is the tough part of a programmer's job: finding the errors in your code. Most of the time you are on your own when doing it but in this case I'll try to do part of it with you hoping the experience will be useful. Before we start, when posting code here, try to paste it between the <pre></pre> tags. It makes it for a much nicer and easier to read code.
int days_in_month[] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
void add_days_to_date (int* mm, int* dd, int* yy, int days_left_to_add)
{
int days_left_in_month;
while (days_left_in_month > 0)Now, ask yourself, what is the value of
days_left_in_month
when the computer tries to evaluate the while loop for the first time? The answer is that it is not known. This is an "uninitialized local variable" bug and it is very common. The compiler has reserved space for the variable but its content can be anything. We have to fix this.while (days_left_in_month > 0)
{
days_left_in_month = days_in_month[*mm] - *dd;
if (days_in_month[2] && is_leap_year (*yy) == true)Oops, here is another bug: you wrote
days_in_month[2]
which is 28 and clearly not zero but what you probably had in mind was more like:if (month == 2 && is_leap_year(*yy) == true)
If we fix the two errors we found your code will be looking something like this:
void add_days_to_date (int* mm, int* dd, int* yy, int days_left_to_add)
{
int days_left_in_month;
days_left_in_month = days_in_month[*mm] - *dd;
if (*mm == 2 && is_leap_year (*yy))
days_left_in_month++;Now it's really the time to start a loop but this loop will have to run until the
days_left_to_add
is greater thandays_left_in_month
. Here I'll stop and let you finish the code. Post back the result and I'll give you more feedback on algorithm and style. EDIT - I see that while I was writing my long convoluting answer Richard had already made the same points in a more concise form :)Mircea