Calendar Program (Hard part is over!)

Hey guys. I have to write a program that, by entering the year, will output a calendar for that year. I have two problems with the code.

1. Inputting a character like "a" or "b" causes an infinite loop.
2. I need the output to be written to a file called "cal.dat", but when I try to do that, it will not compile. So I took out my attempt at that. I just don't understand where to put it.

Here is the code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <iostream>
#include <string> 
#include <iomanip>
#include <fstream>
using namespace std;
void printmonth(const int month, const int startday, bool isleapyear);
void printyear();

int main(void)
{
    int year;
    do
    {
    if(year<1582)
    {
       cout << "Error: please re-enter a value less than 1582 \n";
       cout << '\n';
    }                  
       cout << "Enter a year greater than 1582 to display its yearly calendar: ";
       cin >> year;
       cout << endl;
    } while(year<1582);
        
    cout << "     	  " << year << endl;
    printyear();
}

// ******************************************************************
// * Month Printing Function 			                        *
// ******************************************************************
void printmonth(int month, int startday, bool isleapyear)
{

    int year;
    int daysInMonth[] = { 31,28,31,30,31,30,31,31,30,31,30,31} ;

    string  months[] = { "January", "February", "March", "April", "May", "June", "July", "August", 
        "September", "October", "November", "December"};
    
    string monthHeader;
   
    string dayHeader = string("Sun ") + "Mon " +  "Tue " + 
        "Wed " + "Thu " +  "Fri " + "Sat ";

    cout << '\n';
    
    //Prints the month line
    monthHeader = months[month-1];
    cout << "     	 ";
    cout << monthHeader;
    cout << endl;
    
    
    //Prints the day header line
    cout << dayHeader;
    cout << '\n';
    
    int count,offset;

    offset= 1-startday;
    
    count = daysInMonth[month-1]; //Gets the number of days in the month

   //Adjusts if it is a leap year
    if( isleapyear==true && month==2)
    {
        count++;
    }
    
    //Fills in rows
    int dayNum;
    for (int x = offset; x <= count; x +=7)
    {
        for(dayNum= x; (dayNum < x+7); dayNum++)
        {
            if ( dayNum <=0  || dayNum > count)
            {
                cout << setw(4) << left << setprecision(3) << "    ";;
            }
            else
            {
                cout << setw(4) << left << setprecision(3) << setfill(' ') << dayNum ;
            }

        }
        cout << endl;
    }
}

// ******************************************************************
// * Year Printing Function 			                        *
// ******************************************************************
void printyear()
{
    int year;
    bool isleapyear;
    
    //Checks for leap year
    if(year%400 ==0 || (year%100 != 0 && year%4 == 0))
    {
        isleapyear=true;
    }
    else
    {
        isleapyear=false;
    }
    int month,a,y,m,d;
    for (month = 1; month < 13; month++) //Asks for all 12 months to be printed
  		{
            //Calculates start day
            a=(14-month)/12;
            y=year-a;
            m= month+12*a-2;
            d=(1+y+y/4-y/100 + y/400 + (31*m/12))%7;
            
            //Prints the months
            printmonth(month,d,isleapyear);
  		}
system("pause");
}


EDIT: Please don't get onto me about the pause. The IDE I use will close the program immediately after executing if I don't. That pause will not be in the final product.
Last edited on
You need to check for an error and then clear and ignore the \n it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    int year(0);
    do
    {
       cout << "Enter a year greater than 1582 to display its yearly calendar: ";
       if ( cin >> year ) {
          if(year<1582) {
             cout << "Error: please re-enter a value less than 1582 \n";
             cout << '\n';
          }
          cout << endl;
       }
       else {
          cin.clear();
          cin.ignore(numeric_limits<int>::max(),'\n');
          cout << "Error: must enter a number\n" << endl;
       }
    } while(year<1582);

Declare an ofstream in the main and pass it down by reference into printyear and printmonth.
1
2
3
4
5
ofstream outStrm("cal.txt");
....
printyear(outStrm);
...
printmonth(outStrm);

And then replace cout in printmonth with the out stream you passed in.
Thanks! Finally, no more infinite loop. :D

When I tried that, it would only output one month (December) because of the way I have the program set up.

I wish there was some way to

outStrm << printyear();

But, I'm guessing that's not possible.
You could if printmonth and printyear returned a string or ostringstream.
Build the string in the function and return it.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
string foo(){
   ostringstream outStrm;
   // do something
   for ( int i(0); i < 12; i++)
      outStrm << "Month(" << i << ")\n";
   return outStrm.str();
}
int main(){
   cout << foo(); 
   return 0;
}
Month(0)
Month(1)
Month(2)
Month(3)
Month(4)
Month(5)
Month(6)
Month(7)
Month(8)
Month(9)
Month(10)
Month(11)
Topic archived. No new replies allowed.