Read in string from file, and convert them into enum?

I defined

enum boundaryType_t {inside, inlet, outlet, wall, periodic};

now I have file written like this:

inside outlet

I want my program read the file and when encounter any enum type, instead of treating it as a string, I want the program store it in memory as a enum value.

How can I do that? Thanks!

1
2
3
string s;
ifs>>s;
s // how to convert it to enum??? 
maybe, I should ask question about how to overload istream operator >> for an enum type?
Last edited on
For a straight-up enum, just read the string and compare it to an array of strings. The index of the match is the enum value, and a simple cast will get the proper value.

For an enum with arbitrary values, you also need to provide a lookup table to convert between the match index and the enum value.

For typed enums, you can do it directly in an overloaded operator >>, but for the old enums I would wrap it in an input manipulator.

Hope this helps.
Thanks, Duoas! I want to go with the overloaded operator >> , how can I do that?
Complete example for you.

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
#include <iostream>
#include <string>

//----------------------------------------------------------------------------
// enum class boundaryType_t
//----------------------------------------------------------------------------

#define FOREACH_OP(F) \
  F(inside) \
  F(inlet)  \
  F(outlet) \
  F(wall)   \
  F(periodic)

enum class boundaryType_t
  {
  #define F(x) x,
  FOREACH_OP(F)
  #undef F
  };

namespace
  {
  inline const char* boundaryType_t_names( unsigned n )
    {
    const char* boundary_type_names[] = 
      {
      #define F(x) #x ,
      FOREACH_OP(F)
      #undef F
      NULL
      };
    return boundary_type_names[ n ];
    }  

  inline boundaryType_t boundaryType_t_values( unsigned n )
    {
    boundaryType_t boundary_type_values[] =
      {
      #define F(x) boundaryType_t::x,
      FOREACH_OP(F)
      #undef F
      };
    return boundary_type_values[ n ];
    }
  } // namespace 
  
#undef FOREACH_OP

std::istream& operator >> ( std::istream& ins, boundaryType_t& bt )
  {
  if (!ins) return ins;
  std::string name;
  ins >> name;
  if (ins)
    {
    for (unsigned n = 0; boundaryType_t_names( n ); n++)
      {
      if (name == boundaryType_t_names( n ))
        {
        bt = boundaryType_t_values( n );
        return ins;
        }
      }
    }
  ins.setstate( std::ios::failbit );
  return ins;
  }

std::ostream& operator << ( std::ostream& outs, const boundaryType_t& bt )
  {
  for (unsigned n = 0; boundaryType_t_names( n ); n++)
    {
    if (bt == boundaryType_t_values( n ))
      {
      return outs << boundaryType_t_names( n );
      }
    }
  outs.setstate( std::ios::failbit );
  return outs;
  }
  
  
//----------------------------------------------------------------------------
// Main program
//----------------------------------------------------------------------------

#include <limits>
  
int main()
  {
  using namespace std;
  
  cout << "Enter one of:\n";
  cout << boundaryType_t::inside   << "\n";
  cout << boundaryType_t::inlet    << "\n";
  cout << boundaryType_t::outlet   << "\n";
  cout << boundaryType_t::wall     << "\n";
  cout << boundaryType_t::periodic << "\n";
  cout << "> ";
  
  boundaryType_t bt;
  while (!(cin >> bt))
    {
    cin.clear();
    cin.ignore( numeric_limits <streamsize> ::max(), '\n' );
    cout << "Invalid! Try again\n> ";
    }
  cin.ignore( numeric_limits <streamsize> ::max(), '\n' );
  
  cout << "Good job! You entered " << bt << ".\n";
  return 0;
  }

Hope this helps.
Oh, My god, Thanks a lot, Duoas! I think I need sometime to digest it! Thanks!
Topic archived. No new replies allowed.