从int转换为枚举

时间:2012-05-15 03:50:08

标签: c++

我已声明以下枚举:

  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(),因为我认为枚举是一个整数 - 我如何修复我的代码?

4 个答案:

答案 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>(...)
  • 你应该意识到argv [2]的“0”将映射到枚举标识符“one”,“1”将映射到“five”等...
    • 如果你真的希望“1”映射到“一”,“5”到“五”等,最简单的方法就是改变你的枚举: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;
}