enumeration

1
2
3
4
5
6
7
8
9
typedef enum {JAN = 31, FEB = 59, MAR = 90, APR = 120, MAY = 151, JUN = 181, JUL = 212,
	  AUG = 243, SEP = 273, OCT = 304, NOV = 334}monthList;
bool tryAgain();// <-- this function use JAN,...,NOV
//convertInput also use JAN,...,NOV 
bool convertInput(int getYear, int getMonth, int getDay, int getNumberDays);

int main(){
....


Is my declaration for enum valid?
Or should I use #define to declare all the month list.
My problem is there are two functions that uses that declaration.
Since I don't want global variables and I don't want long codes I used the enum method.
Should I use template? Thanks.
yes it will compile but how come you dont give your enum a name?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
#include <conio.h>
using namespace std;

//you might consider giving your enum a name
enum MONTH {JAN = 31, FEB = 28, MAR = 31, APR = 30, MAY = 31, JUN = 30,
            JUL = 31, AUG = 31, SEP = 30, OCT = 31, NOV = 30, DEC = 31};

int getDays(MONTH month) {
    return month;      
}

int main() {
    
    MONTH month = FEB;
    cout << getDays(month) << '\n';
    getch();
    return 0;
}
28


what are you doing exactly? any good reason to use template?

Is my declaration for enum valid?


I think so.... you're doing it the backasswards C-style typedef way. A simpler way would be like this:

1
2
3
4
5
6
7
enum monthList
{
  JAN = 31,
  FEB = JAN + 28,
  MAR = FEB + 31,
  //...
};


Note how I use the + in there too -- makes it easier to see what you're doing, is less error prone, and spares you the pain of having to do all that math on your own.

Or should I use #define to declare all the month list.


NO!!!

Avoid #define unless it's necessary

Should I use template?


I don't see how a template would help here.

EDIT: doh, too slow =(
Last edited on
blackcoder41
You are abusing the enumeration to use it like that. Also, he did name his enum: monthList.

olredixis
Why the bias? Global variables are perfectly legal, moral, and warrented in many cases. Don't avoid them for the sake of avoiding them.

Also, your functions should not need to mess with cin or cout, unless that is their specific function -- to obtain input or produce output. Functions should do one thing.

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
#include <iostream>
using namespace std;

namespace mycalendar {

  const int days_per_month[] = {
    31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
    };

  // is_leap_year()
  //   Returns whether the given argument represents a leap year.
  //
  bool is_leap_year( int year ) {
    return  ((year % 400) == 0)
     || (   ((year % 100) != 0)
         && ((year %   4) == 0));
    }

  // day_of_year()
  //   Converts a year (for example: 2010), a month (1-12), and a day (1-31)
  //   into the day of the year.
  //   Returns zero on failure.
  //
  int day_of_year(
    int year,
    int month,
    int day
    ) {
    int result = is_leap_year( year ) ? 1 : 0;

    if ((month < 1)
    ||  (month > 12)
    ||  (day < 1)
    ||  (day > (days_per_month[ month ] + result)))
      return 0;

    while (--month)
      result += days_per_month[ month ];

    result += day;

    return result;
    }

  // th()
  //   Return the proper ordinal suffix to a number -- "st", "nd", "rd", or "th".
  //
  const char* th( int n )
    {
    switch (n % 10)
      {
      case 1:  return "st";
      case 2:  return "nd";
      case 3:  return "rd";
      default: return "th";
      }
    }
  }

int main() {

  int year, month, day;

  cout << "What year were you born? " << flush;
  cin >> year;
  cout << "What month were you born (1..12)? " << flush;
  cin >> month;
  cout << "What day were you born? " << flush;
  cin >> day;

  day = mycalendar::day_of_year( year, month, day );

  cout << "You were born on the "
       << day
       << mycalendar::th( day )
       << " day of the year "
       << year
       << ".\n";
  return 0;
  }

Hope this helps.

Fixed commentary in code
Last edited on
Duoas wrote:
blackcoder41
You are abusing the enumeration to use it like that. Also, he did name his enum: monthList.

i dont think he gave enum a name. i believe monthList here is an instance of the enum.

here is your idea
1
2
3
4
5
6
7
enum {JAN = 31, FEB = 59, MAR = 90, APR = 120, MAY = 151, JUN = 181, JUL = 212,
	  AUG = 243, SEP = 273, OCT = 304, NOV = 334}monthList;

void foo() {
    monthList = JAN; //this is correct
    monthList b = FEB; //this is wrong
}


here's mine
1
2
3
4
5
6
7
enum MONTH {JAN = 31, FEB = 28, MAR = 31, APR = 30, MAY = 31, JUN = 30,
            JUL = 31, AUG = 31, SEP = 30, OCT = 31, NOV = 30, DEC = 31};

void foo() {
    MONTH a = JAN; //this is correct
    MONTH b = FEB; //this is correct
}


though i stand to be corrected if i am wrong
Last edited on
okay. thaks for the help.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 enum montList {JAN = 31, FEB = 59, MAR = 90, APR = 120, MAY = 151, JUN = 181, JUL = 212,
	  AUG = 243, SEP = 273, OCT = 304, NOV = 334};
char tryAgain();
bool convertInput(int getYear, int getMonth, int getDay, int getNumberDays);

int main(){
...
}
bool convertInput(int getYear, int getMonth, int getDay, int getNumberDays)
{
if(getMonth == 1) storeMonthDays = 0;
	else if(getMonth == 2) storeMonthDays = JAN;
	else if(getMonth == 3) storeMonthDays = FEB;
...
}

do storeMonthDays = JAN ... is acceptable for professional programming?
since I use enum should I declare

monthList month = JAN;
storeMonthDays = month;

or is storeMonthDays = JAN okay?
thanks. that's my last question about enum.
you can assign enum value to an int but you cant assign int to an enum.
1
2
3
4
//this are all correct
monthList month = JAN;
int storeMonthDays = month;
storeMonthDays = JAN;


and remember that the compiler is a great teacher. . .
Last edited on
but you cant assign int to an enum
Yes, you can.
month=(monthList)storeMonthDays;

the compiler is a great teacher
I hope you're ready to learn some hard lessons. For example, "the compiler isn't always right".
Thanks everyone. I gained more knowledge about enum method now.
I found another way of solving my problem.

Thanks to Duoas. I will use this code instead of enum.

const int days_per_month[] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
};
Yes, you can.
month=(monthList)storeMonthDays;
did you cast the int to enum? i did not say except if you cast it.

I hope you're ready to learn some hard lessons. For example, "the compiler isn't always right".
i guess you're right. thanks.
olredixsis
Don't forget to account for February's variable number of days like I did in my example above. It has 28 in normal years, and 29 in leap years. Hence, the day of the year for the first of each month following February varies depending on whether or not it is a leap year.

blackcoder41
i dont think he gave enum a name. i believe monthList here is an instance of the enum.

Actually, he made monthList a typedef for the otherwise unnamed enum.

typedef enum { ... } monthList;

Hence:
1
2
  monthList         = JAN;  // this is not correct
  monthList a_month = FEB;  // this is correct 

Hope this helps.
@Duoas:

Your th() function does not return the correct value for any
number of the form 100 * x + 11, 100 * x + 12, or 100 * x + 13.



Yoinks! So it doesn't.

(It just goes to show what happens when you type something off the top of your head without testing...)

Let's see if this gets it better:
1
2
3
4
5
6
7
8
9
10
11
12
const char* th( int n )
  {
  if (n < 0) n = -n;
  if (((n % 100) / 10) != 1)
    switch (n % 10)
      {
      case 1: return "st";
      case 2: return "nd";
      case 3: return "rd";
      }
  return "th";
  }

Sorry!
Duoas
Yeah I will account for February's variable number for leapyear.
Topic archived. No new replies allowed.