# Thread: calandar program almost works except a major problem.

1. ## calandar program almost works except a major problem.

Code:
```#include <stdio.h>
void getMonthYear(int *month, int *year);
int toJulian(int month, int day, int year);
int daysInMonth(int month, int year);
int leapYear(int year);
long yearsToDays(int year);
void printCalendar(int startDay, int numDays);

#define MAX_COL 7
//#define JAN_1_1900_START_DAY	2	//starts on Monday
//#define JAN_1_1900_START_DAY_OFFSET	(JAN_1_1900_START_DAY-1)	//Since Sunday is day 1

void main(void)//1 jan 1900= julian day 1, use julian day to calculate month day etc with remainder function
{
int month, year, startDay, numDays;
getMonthYear(&month, &year);

//added 1 below because 1-1-1900 starts on a monday
startDay = (toJulian(month, 1, year) + yearsToDays(year)) % 7;//1/1/1900 starts on monday, offset goes outside the order of ops here
numDays = daysInMonth(month, year);
printCalendar(startDay, numDays);
}

void getMonthYear(int *month, int *year)
{
printf("Enter month: ");
scanf_s("%d", month);//don't put pointer * in here, already a pointer from above
/*do{
printf("You entered an invalid month");
}while(*month < 1 || *month > 12);*/
printf("Enter year: ");
scanf_s("%d", year);
}

int toJulian(int month, int day, int year)//can't return bigger than 366
{
switch(month-1)// needs2calc month b4 the one of input
{//don't hardcode?
//case 12: day += 31;//dec
case 11: day += 30;//nov
case 10: day += 31;//oct
case 9: day += 30;//sep
case 8: day += 31;//aug
case 7: day += 31;//july
case 6: day += 30;//june
case 5: day += 31;//may
case 4: day += 30; //apr
case 3: day += 31; //mar
case 2: day += 28 + leapYear(year);//feb
case 1: day += 31;//jan
}
return day;
}

int daysInMonth(int month, int year)
{
switch(month)
{//don't hardcode?
case 12:
return 31;//dec
case 11:
return 30;//nov
case 10:
return 31;//oct
case 9:
return 30;//sep
case 8:
return 31;//aug
case 7:
return 31;//july
case 6:
return 30;//june
case 5:
return 31;//may
case 4:
return 30; //apr
case 3:
return 31; //mar
case 2:
return (28 + leapYear(year));//feb
case 1:
return 31;//jan
}

return 0;//put excredit here maybe
}

int leapYear(int year)//put 2 conditions 1 for centenials one for noncenttentials
{

if(year % 400 == 0 || (year % 100 != 0 && year % 4 == 0))//make 100&400 centeial conditions 1 and 2
return 1;
else
return 0;
}
long yearsToDays(int year)
{
long juliandays = 0;
int julianyr;
for(julianyr = 1900; julianyr < year; julianyr++)//years to days f()
{
juliandays += (365 + leapYear(julianyr));//or day=
}

//add 365 or 366 from leap years
return juliandays;//put extra cred here maybe
}
void printCalendar(int startDay,int numDays)
{//print 1 day@time, \n after sat
int column, showdays;

for (column = 0; column < startDay; ++column)
{
printf("  0");
}

for(showdays = 1; showdays <= numDays; showdays++)
{
if(column <= MAX_COL)
{
printf("%3d", showdays);
}
else if(column >= MAX_COL)
{
printf("\n");
column = 0;
}
column++;
}
//wrong somewhere

}```
output:
Code:
```Enter month: 4
Enter year: 2011
Su   M Tu  W Th  F Sa
0  0  0  0  0  1  2  3
5  6  7  8  9 10 11
13 14 15 16 17 18 19
21 22 23 24 25 26 27
29 30Press any key to continue . . .```
the 3 is not in the right spot(it should be in the next line under Su), i have been working 3 hours trying to figure out how to fix this thing manipulating only my printCalendar(int startDay,int numDays) function, and i'm going insane

2. Your logic is a little over complicate and out of order. At times like this, it's usually best to work out your strategy on paper, then run through it by hand. Lastly, try to implement it, and while you're working out the details in code, put in plenty of useful printf statements giving the value of key variables throughout the function.

What you want to do is the following: Every time through the loop, you want to print showdays. Next, increment column to signify we "moved on". Lastly, if column is equal to MAX_COL, print a new line and reset it.
Code:
```for showdays from 1 to numDays
print showdays
column++
if column == MAX_COL
print a new line
set column to 0```

3. thanks, i finally figured it outmyself
Code:
```int column, showdays;//<---might be useless

for (column = 0; column < startDay; column++)
{
printf("  0");
}

//column = 5 for 4-1-2011
for(showdays = 1; showdays <= numDays; showdays++, column++)
{

if(column < MAX_COL)
{
printf("%3d", showdays);
}
if(column == MAX_COL)//if
{
printf("%3d\n", showdays);
column = -1;//set to -1 because if enters loop again will become = to 0
}
}```
like this but yours look so much less complex, this is why i'm going to be doing the biological stuff in engineering not the programming

4. I think you're missing a key element to both biology and programming: following instructions. How many if's are inside the for loop I gave you? What's inside the if (hint: below it and more indented)? What's outside the if? What order do all these statements go in? Take another crack at it, using my pseudo code as a template. You can translate it line-for-line to simple C statements.

5. thanks i understand your code also,
now i'm wondering why when i add
Code:
```void getMonthYear(int *month, int *year)
{
printf("Enter month: ");
scanf_s("%d", month);//don't put pointer * in here, already a pointer from above

do{
printf("You entered an invalid month\n");
printf("Enter month: ");
scanf_s("%d", month);
}while(*month < 1 || *month > 12);

printf("Enter year: ");
scanf_s("%d", year);
}```
it outputs "you entered an invalid month" for the first prompting automatically even if i enter in a valid month(from my stupid human perspective at least)

6. never mind figured out the above^

your main function should never begin and end like this:
Code:
```void main(void)
{
...
}```
Instead, it should look like this:
Code:
```int main()
{
...

return 0;
}```
Function main() should always return an integer value to the operating system.

8. Originally Posted by Steve A.
your main function should never begin and end like this:
Code:
```void main(void)
{
...
}```
Instead, it should look like this:
Code:
```int main()
{
...

return 0;
}```
Function main() should always return an integer value to the operating system.
Actually, for maximum compatibility it should be
Code:
```int main (void)
{

return exitvalue;
}```
The reason being that some compilers interpret () as "any number of parameters" where (void) means "no parameters".
The return at the end need not return 0 (although it most often does) but returned values can be useful in batch files.