3

我已经声明了以下枚举:

  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() 因为我认为 enum 是一个 int - 我该如何修复我的代码?

4

4 回答 4

7

你必须明确地转换它:

mp=static_cast<periods>(atoi(min_prd.c_str()));
于 2012-05-15T03:53:15.537 回答
3

我已经声明了以下枚举:

enum periods {one, five, ten, fifteen, thirty};

现在我想在我的主函数中将它作为命令行参数传递。

periods mp = atoi(argv[2]);   // simplified for answer...

所以,有几个问题:

  • 您需要将返回的 intatoi转换为枚举类型...static_cast<periods>(...)
  • 您应该意识到“0”的 argv[2] 将映射到枚举标识符“一”,“1”将映射到“五”等...
    • 如果您实际上希望 "1" 映射到 "one"、"5" 到 "5" 等,最简单的方法是更改​​您的 enum: 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");
}

(当有更多情况时,使用 astd::map或 sortedstd::vector来跟踪这些关联并不少见,它允许可重用​​的算法和相同的数据支持从枚举数值到文本标识符的转换。)

于 2012-05-15T03:59:17.837 回答
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()));
}

但是 thenatoi应该用于将 c-string 转换为 int,因为不检查输入字符串中的错误,因此它是unsafeatoi

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

希望有帮助。

于 2012-06-04T19:53:09.563 回答
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;
}
于 2012-05-15T04:04:29.680 回答