Implementing function of type Month

Asked

Viewed 76 times

-1

Good morning guys blz?

was implementing a Month type function that returns Month I tried to use static_cast to convert to Month type but from conversion errors to same. The program is this below:

#include <regex>
#include <array>
#include <vector>
#include <chrono>
#include <cassert>
#include <utility>
#include <iostream>

enum Month
{
  Jan = 1, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec
};

// structured binding, Datastructure for string to num conversion in month(.i.e."Mar" Month to 3)
std::array<std::pair<std::string, Month>, 12> monthinfo = 
{
    std::make_pair("Jan", Month::Jan),
    std::make_pair("Feb", Month::Feb),
    std::make_pair("Mar", Month::Mar),
    std::make_pair("Apr", Month::Apr),
    std::make_pair("May", Month::May),
    std::make_pair("Jun", Month::Jun),
    std::make_pair("Jul", Month::Jul),
    std::make_pair("Aug", Month::Aug),
    std::make_pair("Sep", Month::Sep),
    std::make_pair("Oct", Month::Oct),
    std::make_pair("Nov", Month::Nov),
    std::make_pair("Dec", Month::Dec)
};

// concrete daytime structure to store the data
//template<typename T1, typename T2 = std::string>
template<class T1, class T2 = std::string>
struct DayTime
{
    T1 day      = T1();
    T1 month    = T1();
    T1 year     = T1();
    T1 hour     = T1();
    T1 min      = T1();
    T1 second   = T1();
    T2 daystr   = T2();
    T2 dtstring = T2();
};


// main class which would fetech/parse the current time and provide to the client
class CurrentDateTime
{
   DayTime<std::string> ParseDateTime(const std::string&);
   void StrToNumber(const DayTime<std::string>&);
   Month GetMonth(const std::string&);
   DayTime<int> dt;

 public:

    CurrentDateTime();
    virtual ~CurrentDateTime(){};

    int      GetDay() const { return dt.day;    }
    Month  GetMonth() const { return dt.month;  }
    int     GetYear() const { return dt.year;   }
    int     GetHour() const { return dt.hour;   }
    int      GetMin() const { return dt.min;    }
    int   GetSecond() const { return dt.second; }
    std::string   GetDayStr() const { return dt.daystr; }
};

CurrentDateTime::CurrentDateTime()
{
    //fetch/store current local-daytime information
    auto tp = std::chrono::system_clock::now();
    time_t cstyle_t = std::chrono::system_clock::to_time_t(tp);
    char* cstyleinfo = std::ctime(&cstyle_t);
    // copy(deep) the data into the std::string as ::ctime() provides static data 
    // which might be overwritten in case someone call it again.
    std::string currentinfo(cstyleinfo);

    //parse/store  the information
    auto dtstr = ParseDateTime(currentinfo);
    StrToNumber(dtstr);
}


DayTime<std::string> CurrentDateTime::ParseDateTime(const std::string& information)
{
    DayTime<std::string> info;
    std::regex dtimeregex(R"(^(\w{3}) (\w{3}) (\d{2}) (\d{2}):(\d{2}):(\d{2}) (\d{4}))");
    std::smatch match;

    if (std::regex_search(information, match, dtimeregex)) 
    {
        // Match the group and subgroups by regex parser.
        auto index = 0;
        info.dtstring = match[index++];
        info.daystr   = match[index++];
        info.month    = match[index++];
        info.day      = match[index++];
        info.hour     = match[index++];
        info.min      = match[index++];
        info.second   = match[index++];
        info.year     = match[index++];
    }

    return info;
}

Month CurrentDateTime::GetMonth(const std::string& input) const 
{
    for (const auto& itr : monthinfo) 
    {
        if (itr.first == input)
      return itr.second;
      //return static_cast<Month>(itr.second);
    }
    assert(false && "Invalid month name");
    // Or return a default month if it makes sense.
    // Another possibility is extending the enum Month to 
    // add an invalid dummy value, throwing an exception, etc.
}

void CurrentDateTime::StrToNumber(const DayTime<std::string>& information)
{
    dt.dtstring = information.dtstring;
    dt.daystr   = information.daystr;
    dt.month    = GetMonth(information.month);

    dt.day      = std::stoi(information.day.c_str());
    dt.hour     = std::stoi(information.hour.c_str());
    dt.min      = std::stoi(information.min.c_str());
    dt.second   = std::stoi(information.second.c_str());
    dt.year     = std::stoi(information.year.c_str());
}


int main()
{
  CurrentDateTime current = *new CurrentDateTime();

    std::cout << "\n\tCurrent Day....: " << current.GetDayStr()
              << "\n\tCurrent Date...: " << current.GetDay()
              << "\n\tCurrent Month..: " << current.GetMonth()
              << "\n\tCurrent Year...: " << current.GetYear()
              << "\n\tCurrent Hour...: " << current.GetHour()
              << "\n\tCurrent Min....: " << current.GetMin()
              << "\n\tCurrent Second.: " << current.GetSecond() 
              << "\n\n";
    return 0;
} 

because the program should return something like:

    Current Day....: Tue
    Current Date...: 23
    Current Month..: 1
    Current Year...: 2018
    Current Hour...: 8
    Current Min....: 50
    Current Second.: 29

but it generates the following error below:

Ex2.cxx: In member function ‘Month CurrentDateTime::GetMonth() const’:
Ex2.cxx:62:49: error: invalid conversion from ‘int’ to ‘Month’ [-fpermissive]
             Month  GetMonth() const { return dt.month;  }
                                              ~~~^~~~~
Ex2.cxx: At global scope:
Ex2.cxx:108:7: error: prototype for ‘Month CurrentDateTime::GetMonth(const string&) const’ does not match any in class ‘CurrentDateTime’
 Month CurrentDateTime::GetMonth(const std::string& input) const
       ^~~~~~~~~~~~~~~
Ex2.cxx:62:20: error: candidates are: Month CurrentDateTime::GetMonth() const
             Month  GetMonth() const { return dt.month;  }
                    ^~~~~~~~
Ex2.cxx:53:10: error:                 Month CurrentDateTime::GetMonth(const string&)
    Month GetMonth(const std::string&);

1 answer

1


Your code has two problems that are generating these errors:

1) Conversion between integers and enumerations

On line 62 you are trying to convert a value dt.month (which is integer type) for a value of type Month which is an enumeration. Although enumerations in C++ are stored as integer values internally, this type of conversion is not done implicitly (because the integer value could fall outside the enumeration values). Either you create a function to do this (which is the most correct and secure option) or simply replace the line

Month  GetMonth() const { return dt.month;  }

For

Month  GetMonth() const { return static_cast<Month>(dt.month);  }

This is the fastest option to solve the problem.

2) Declaration of method other than implementation

You are declaring the method CurrentDateTime::GetMonth(const std::string&) in class CurrentDateTime without const, but is trying to define this method using const lower. You must decide what you want. The best option seems to be simply add const the declaration of the method, that is, replace the line

Month GetMonth(const std::string&);

For

Month GetMonth(const std::string&) const;

The corrected version of your code is here: https://ideone.com/IxbffB

P.S.: People around here don’t like it very much when you simply copy code with error and wait for others to debug it for you. Next time, if you have a question about any of the topics that generated the error, put the question on the topic as question ;)

  • then regarding the different statement of the implementation I did returning int and this working..

  • Returning int works because you’re doing the static_cast implicitly.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.