我已声明以下枚举:
enum periods {one, five, ten, fifteen, thirty};
现在我想在主函数中将它作为命令行参数传递。
int main(int argc, char* argv[]) {
periods mp;
if (argc == 2) {
std::string min_prd(argv[2]);
mp=atoi(min_prd.c_str());
}
并且编译器抱怨:
error: invalid conversion from ‘int’ to ‘periods’
我做了atoi(),因为我认为枚举是一个整数 - 我如何修复我的代码?
答案 0 :(得分:6)
你必须明确地施展它:
mp=static_cast<periods>(atoi(min_prd.c_str()));
答案 1 :(得分:3)
我已声明以下枚举:
enum periods {one, five, ten, fifteen, thirty};
现在我想在主函数中将它作为命令行参数传递。
periods mp = atoi(argv[2]); // simplified for answer...
所以,有几个问题:
atoi
返回的int强制转换为枚举类型... static_cast<periods>(...)
enum periods { one = 1, five = 5, ten = 10, fifteen = 15, thirty = 30 };
,但你的例子显然有点做作,所以你最好创建一个函数:
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");
}
(当有更多情况时,使用std::map
或排序std::vector
跟踪这些关联的情况并不少见,它允许可重复使用的算法和相同的数据支持从枚举数值转换为文本标识符。)
答案 2 :(得分:3)
直截了当的解决方案是使用static_cast
(正如另一个答案已经发布的那样):
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()));
}
但是atoi
应该不用于将c-string转换为int,因为atoi
不检查输入字符串中的错误,因此它是的不安全强>
C ++ 11提供更安全的转换功能,因此您可以将std::stoi
用作:
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;
}
现在这是一个更好的解决方案。
但是,您可以使用另一种解决方案:
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;
}
}
现在问题是,我们应该如何实现to_period
功能?
请注意,此解决方案假定枚举值one
的命令行参数将是其字符串表示形式,即它将是"one"
而不是1
,这是整数表示强>
我会将此解决方案实现为:
首先创建一个名为period_items.h
的头文件:
//period_items.h
E(one)
E(five)
E(ten)
E(fifteen)
E(thirty)
然后创建另一个名为period.h
的头文件:
//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;
}
现在您只需添加period.h
并使用to_period
功能即可。 : - )
请注意,在替代解决方案中,我使用的是单数形式而不是复数形式,这意味着我使用了period
而不是periods
。我认为period
是合适的。
您还可以将此功能添加到period.h
:
std::string to_string(period value)
{
#define E(item) if(value == item) return #item;
#include "period_items.h"
#undef E
return "<error>";
}
现在,你可以这样写:
#include "period.h"
period v = to_period(argv[1)); //string to period
std::string s = to_string(v); //period to string
希望有所帮助。
答案 3 :(得分:2)
随机猜测,你真正想要的更像是:
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;
}