regex - Mapping c++ string to an enum in order to take user input -


i'm trying design class represent card i've decided use enums represent rank , suit. however, need able take input user and, unfortunately, it's not possible take enum directly cin.

for reason, intending take in string , use std::map map each string enum value represents (as described in this question). didn't want input case sensitive created regex should shift characters lowercase before matching.

the code came here:

istream& operator>>(istream& is, card& d) { std::map<std::string,card::rank> mr; std::map<std::string,card::suit> ms; mr[std::regex("/two/i")] = card::two; mr[std::regex("/three/i")] = card::three; mr[std::regex("/two/i")] = card::four; mr[std::regex("/two/i")] = card::five; mr[std::regex("/two/i")] = card::six; mr[std::regex("/two/i")] = card::seven; mr[std::regex("/two/i")] = card::eight; mr[std::regex("/two/i")] = card::nine; mr[std::regex("/two/i")] = card::ten; mr[std::regex("/two/i")] = card::jack; mr[std::regex("/two/i")] = card::queen; mr[std::regex("/two/i")] = card::king; ms[std::regex("/clubs/i")] = card::clubs; ms[std::regex("/diamonds/i")] = card::diamonds; ms[std::regex("/hearts/i")] = card::hearts; ms[std::regex("/spades/i")] = card::spades;  string srank, ssuit; char c1;  if (is >> srank >> c1 >> ssuit) {     if (c1 == 'of')     {         card::rank rank = mr[srank];         card::suit suit = ms[ssuit];         d = card(rank, suit);     }     else     {        is.clear(ios_base::failbit);     } }  return is; } 

however, on compile receive error:

error c2679: binary '[' : no operator found takes right-hand operand of type 'std::basic_regex<_elem>' (or there no acceptable conversion)             [           _elem=char       ]       c:\program files (x86)\microsoft visual studio 11.0\vc\include\map(173): 'card::rank &std::map<_kty,_ty>::operator [](std::basic_string<_elem,_traits,_alloc> &&)'             [           _kty=std::string,           _ty=card::rank,           _elem=char,           _traits=std::char_traits<char>,           _alloc=std::allocator<char>       ]       c:\program files (x86)\microsoft visual studio 11.0\vc\include\map(190): or       'card::rank &std::map<_kty,_ty>::operator [](const std::basic_string<_elem,_traits,_alloc> &)'             [           _kty=std::string,           _ty=card::rank,           _elem=char,           _traits=std::char_traits<char>,           _alloc=std::allocator<char>       ]       while trying match argument list '(std::map<_kty,_ty>, std::basic_regex<_elem>)'             [           _kty=std::string,           _ty=card::rank       ]       ,       [           _elem=char       ]  etc. 

i've never used map before , i'm not understanding i've done wrong; instructions i've managed dig up, seems me should work.

solution based on have:

std::regex not std::string, these different types. doubt, if can sensible results, using std::regex map key. what's more, std::map never work expected. if test string against list of regexes , pick 1 matches, have that: iterate on regexes , test each one. if going laxer these regexes, you'll need.

much easier approach convert read strings lowercase, , using standard map of strings. like:

#include <cctype>  static inline void stringtolower(std::string &s) {     (uint = 0; < s.size(); ++i) {         s[i] = tolower(s[i]);     } }  istream& operator>>(istream& is, card& d) {     std::map<std::string,card::rank> mr;     std::map<std::string,card::suit> ms;     mr["two"] = card::two;     mr["three"] = card::three;     ...     mr["king"] = card::king;      ms["clubs"] = card::clubs;     ...      string srank, ssuit, c1;      if (is >> srank >> c1 >> ssuit)     {         stringtolower(c1);         if (c1 == "of")         {             stringtolower(srank);             stringtolower(ssuit);             card::rank rank = mr[srank];             card::suit suit = ms[ssuit];             d = card(rank, suit);         }         else         {             is.clear(ios_base::failbit);         }     }      return is; } 

note, changed c1 string. in yout version, c1 first character after srank (it whiltespace). also, char value can never equal 'of' ('of' of type int). changed "of" (double quotes), of type const char *. remember, wouldn't work properly, if c1 char*.

by way, innefficient create mr , ms maps every << call separately. consider using kind of singleton. possible solution may like:

static std::map<std::string,card::rank> createmr() {     std::map<std::string,card::rank> mr;     mr["two"] = card::two;     mr["three"] = card::three;     ...     mr["king"] = card::king;     return mr; }  static std::map<std::string,card::rank> createms() {     std::map<std::string,card::rank> ms;     ms["clubs"] = card::clubs;     ...     return ms; }  istream& operator>>(istream& is, card& d) {     static std::map<std::string,card::rank> mr = createmr(); // note `static` keyword     static std::map<std::string,card::suit> ms = createms();     ... } 

explanation: used static keyword here, in 2 different kinds of places. 1 before functin declaration. static means, functions not available in other source files. used in mr , ms declarations. there means, these variables common calls of function, in defined (in case, operator>>). 1 consequence of is, createmr() , createms() called once, in first call of operator.

possibly better way define mr , ms outside function:

static std::map<std::string,card::rank> mr = createmr(); // note `static` keyword static std::map<std::string,card::suit> ms = createms();  istream& operator>>(istream& is, card& d) {     ... } 

static keyword here means, these variables (which global), not accessible outside source file. may omitted here, practice mark static functions , global variables, not going used outside.


Comments

Popular posts from this blog

PHPMotion implementation - URL based videos (Hosted on separate location) -

javascript - Using Windows Media Player as video fallback for video tag -

c# - Unity IoC Lifetime per HttpRequest for UserStore -