Practicing Enumeration

Hi there.
I'm practicing enumeration. I wrote this program in which you enter the day of the week and the program tells you what day yesterday was, and what day tomorrow will be. Here's the source code?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

int main()
{
    enum Day{Saturday,Sunday, Monday, Tuesday, Wednesday, Thursday, Friday};
    Day d1=Friday;
    cout<<"Today: "<<d1<<endl;
    cout<<"Yesterday: "<<d1-1<<endl;
    cout<<"Tomorrow: "<<d1+1<<endl;
    system ("pause");
    return 0;
}


the output of the program comes as numbers:
Today:6
yesterday:5
tomorrow: 7

I have two questions:
1. How can I output days instead of numbers?
2. What's the simplest way to get this piece of code to work:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
using namespace std;

int main()
{
    enum Day{Saturday,Sunday, Monday, Tuesday, Wednesday, Thursday, Friday};
    Day d1;
    cin>>d1; //This line creates problems
    cout<<"Today: "<<d1<<endl;
    cout<<"Yesterday: "<<d1-1<<endl;
    cout<<"Tomorrow: "<<d1+1<<endl;
    system ("pause");
    return 0;
}


1. How can I output days instead of numbers?

You must have a string mapping of numbers to days for you to output string representation of days instead of numbers. You may define a vector<string> type and add 7 elements to it for every day of the week and you may access the individual day using the vector's subscript operator like v[0], v[1] etc.


2. What's the simplest way to get this piece of code to work:

You are trying to pass an integer to an enum. This will not work without an explicit cast. You may try to do cin >> i //i is an int and then do d1 = (Day)i. However, you may use vector as suggested in 1 above.

There is also a minor problem in your program. When you increment d1 you may go past the max of 6 in which case you will have to wrap around to 0. For instance, if you increment friday, you will need to go to Saturday which has value of 0. So is the case with decrementing Saturday too and your code should take care of these 2 cases.
How can I output days instead of numbers?

You could you switch .. case to fix that.

try the following:

1
2
3
4
5
6
7
8
9
10
switch(Day)
{
case Saturday:
    cout << "Saturday";
    break;
case Sunday:
    cout << "Sunday";
    break;
[...]
}


You could put that code in a function outside your main(). You would also need to declare your enum outside the main as well. In that way, instead of displaying d1 you could call your function by passing the d1 value in it and the switch .. case will display your day in a string.

2. What's the simplest way to get this piece of code to work:

naivnomore is absolutely right. Although if you are looking for an easier solution then vector (in case you don't know how to use them), you could simply do a cout and explain say the values that equals each days and use a integer (like naivnomore suggested) to get that value.
The best way to display the days would be

cout << "Saturday = " << Saturday << ", Sunday = " << Sunday [...]

that way you will be sure that you always have the good value. For example if you put Saturday at the end of the enum list it will become 6 and you wouldn't need to correct that in your cout.
This is the most transparent way I could come up with.

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
//Do not assing values to the enum members, otherwise the functions will fail
enum Day{Saturday,Sunday, Monday, Tuesday, Wednesday, Thursday, Friday}; 
std::string daystrtable[7] = { "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };

std::ostream& operator<<(std::ostream& os, Day d) {    
    os << daystrtable[static_cast<int>(d)]; //Don't look here. Never cast to or from enums.
    return os;
}

std::istream& operator>>(std::istream& is, Day& d) {
    std::string str;
    is >> str;
    
    std::string *find_str = std::find(daystrtable, daystrtable+7, str);
    
    if (find_str == daystrtable+7) { //No match found
        is.setstate(std::ios_base::failbit); //Set failbit
    } else {
        d = static_cast<Day>(find_str - daystrtable); //Don't look here. Never cast to or from enums.
    }
    return is;
}


int main() {   
    
    Day d = Sunday; //Initalize to silence warnings
    std::cout << "Enter a day : ";
    
    if(!(std::cin >> d)) {
        std::cout << "\nFailed to read value" << std::endl;
    } else {
        std::cout << "\nYou've entered " << d << std::endl;
    }
}
Last edited on
std::ostream& operator<<(std::ostream& os, Day d) {
os << daystrtable[static_cast<int>(d)]; //Don't look here. Never cast to or from enums.
return os;
}


enums can be used anywhere an int is required - you dont even need to cast it
so
os << daystrtable[d]; //ok


It is casting from int to enum that maybe an issue.
enums can be used anywhere an int is required - you dont even need to cast it
so
os << daystrtable[d]; //ok

I know... Still in my opinion enums shouldn't be used as integral types, without explicit casting. This is just a matter of style.
Topic archived. No new replies allowed.