I have declared the following enum :
enum periods {one, five, ten, fifteen, thirty};
and now I want to pass it as a commandline argument
I have declared the following enum :
enum periods {one, five, ten, fifteen, thirty};
and now I want to pass it as a commandline argument in my main function.
periods mp = atoi(argv[2]); // simplified for answer...
So, there are several issues:
atoi
to the enum type... static_cast<periods>(...)
enum periods { one = 1, five = 5, ten = 10, fifteen = 15, thirty = 30 };
, but your example's obviously a little contrived so it's impossible to guess what will work best for your real needsYou're better off creating a function:
periods to_periods(const std::string& s)
{
if (s == "one") return one;
if (s == "five") return five;
if (s == "ten") return ten;
if (s == "fifteen") return fifteen;
if (s == "thirty") return thirty;
throw std::runtime_error("invalid conversion from text to periods");
}
(When there are more cases, it's not uncommon to use a std::map
or sorted std::vector
to track these associations, and it allows reusable algorithms and the same data to support conversions from enum numeric value to textual identifier.)
You have to explicitly cast it:
mp=static_cast<periods>(atoi(min_prd.c_str()));
At a random guess, what you really want is something more like:
periods mp;
if (argc < 2) {
mp=one; // default value
} else if (strcmp(argv[1], "one")==0) {
mp=one;
} else if (strcmp(argv[1], "five")==0) {
mp=five;
} else if (strcmp(argv[1], "ten")==0) {
mp=ten;
} else if (strcmp(argv[1], "fifteen")==0) {
mp=fifteen;
} else if (strcmp(argv[1], "thirty")==0) {
mp=thirty;
} else {
fprintf(stderr, "I can't possibly comprehend periods = '%s'\n", argv[1]);
return -1;
}
The straightforward solution is to use static_cast
(as the other answer has already posted it):
periods mp;
if (argc == 2)
{
std::string min_prd(argv[1]); //the index should be 1
mp = static_cast<periods>(atoi(min_prd.c_str()));
}
But then atoi
should not be used to convert the c-string into int, because atoi
doesn't check for error in the input string, hence it is unsafe.
C++11 provides safer conversion functions, so you could use std::stoi as:
try
{
periods mp;
if (argc == 2)
{
//std::stoi could throw exception on error in input
mp = static_cast<periods>(std::stoi(argv[1]));
}
//use mp here
}
catch(std::exception const & e)
{
std::cout << "exception caught with message : " << e.what() << std::endl;
}
Now that is a better solution.
However, there is an alternative solution which you could use as:
period mp;
if (argc == 2)
{
mp = to_period(argv[1]); //how should we implement it?
if (mp == period_end)
{
std::cout << "command line input error" << std::endl;
return 0;
}
}
Now the question is, how should we implement to_period
function?
Note that this solution assumes that the command line argument for enum value one
would be its string representation, i.e it would be "one"
instead of 1
which is integral representation.
I would implement this solution as:
First create a header file called period_items.h
as:
//period_items.h
E(one)
E(five)
E(ten)
E(fifteen)
E(thirty)
then create another header file called period.h
as:
//period.h
#include <string>
enum period
{
#define E(item) item,
#include "period_items.h"
#undef E
period_end
};
period to_period(std::string const & name)
{
#define E(item) if(name == #item) return item;
#include "period_items.h"
#undef E
return period_end;
}
Now you can simply include period.h
and use to_period
function. :-)
Note that in the alternative solution, I've used singular form rather than plural form, means I've used period
rather than periods
. I feel period
is appropriate.
You could also add this function to period.h
as:
std::string to_string(period value)
{
#define E(item) if(value == item) return #item;
#include "period_items.h"
#undef E
return "<error>";
}
Now, you could write this:
#include "period.h"
period v = to_period(argv[1)); //string to period
std::string s = to_string(v); //period to string
Hope that helps.