我正在尝试使用getsubopt来解析c ++中的一些子选项。我有以下代码。
enum LOG_LEVELS {LOG_QUIET, LOG_NORMAL, LOG_VERBOSE, LOG_DEBUG};
int parse_log_level(char *log_level){
/* Define valid log options. */
char *const log_opts[] =
{
"quiet",
"normal",
"verbose",
"debug",
NULL
}; /* <- First set of warnings */
char* value;
/* Loop through each option and check for valid log options. */
while (log_level != '\0'){
switch (getsubopt (&log_level, log_opts, &value))
{
case LOG_QUIET:
return LOG_QUIET;
break;
case LOG_NORMAL:
return LOG_NORMAL;
break;
case LOG_VERBOSE:
return LOG_VERBOSE;
break;
case LOG_DEBUG:
return LOG_DEBUG;
break;
default:
std::cout << "Only the following log options are valid"
<< std::endl << std::endl << "\tquiet"
<< std::endl << "\tnormal"
<< std::endl << "\tverbose"
<< std::endl << "\tdebug" << std::endl;
return -1;
break;
}
}
}
当我尝试编译时,我收到以下错误。
option_parser.cpp: In function 'int parse_log_level(char*)':
option_parser.cpp:35: warning: deprecated conversion from string const to 'char*'
option_parser.cpp:35: warning: deprecated conversion from string const to 'char*'
option_parser.cpp:35: warning: deprecated conversion from string const to 'char*'
option_parser.cpp:35: warning: deprecated conversion from string const to 'char*'
正如您可能注意到的,我在某种程度上偏离了以下提供的示例: getsubopt example
即,我使用过:
char *const log_opts[] =
{
"quiet",
"normal",
"verbose",
"debug",
NULL
}; /* <- First set of warnings */
取代我想象的将是他们的代码版本:
char *const log_opts[] =
{
[LOG_QUIET] = "quiet", /* <- New error */
[LOG_NORMAL] = "normal", /* <- New error */
[LOG_VERBOSE] = "verbose", /* <- New error */
[LOG_DEBUG] = "debug", /* <- New error */
NULL
};
当我尝试上面的代码时,我收到以下错误
option_parser.cpp: In function 'int parse_log_level(char*)':
option_parser.cpp:30: error: expected primary-expression before '[' token
option_parser.cpp:31: error: expected primary-expression before '[' token
option_parser.cpp:32: error: expected primary-expression before '[' token
option_parser.cpp:33: error: expected primary-expression before '[' token
我在教程中选择了我的格式,因为它避免了错误,我不理解语法,即我不理解char * const数组声明中的[FOO] = "bar"
语法。我也注意到在示例中他们的枚举没有命名,而我的等价LOG_LEVELS
是。我的枚举在我的程序的其他地方工作。最后,我注意到他们的枚举对第一个项目有类似的语法,即RO_OPT = 0,
的上下文中的enum {RO_OPT = 0, RW_OPT, NAME_OPT};
。
我曾尝试在网上其他地方寻找类似的结构,但没有找到任何帮助我解决这个问题的东西。我希望在尝试尽可能清楚地提出这个问题时,我并不太啰嗦。
答案 0 :(得分:0)
您的代码是正确的。在我看来,getsubopt
的原型是不正确的。 tokens
应该是const char * const *
。据推测,这是一个历史错误,无法轻易纠正。
有几种丑陋的方法可以解决这个问题。
您可以为每个选项创建本地非const char数组:
char tok_quiet[] = "quiet";
char tok_normal[] = "normal";
char tok_verbose[] = "verbose";
char tok_debug[] = "debug";
char *const log_opts[] =
{
tok_quiet,
tok_normal,
tok_verbose,
tok_debug,
NULL
};
或者您可以使用文字数组作为标记:
char *const log_opts[] =
{
(char[]){'q','u','i','e','t',0},
(char[]){'n','o','r','m','a','l',0},
(char[]){'v','e','r','b','o','s','e',0},
(char[]){'d','e','b','u','g',0},
NULL
};
我认为你会同意这两件事都很令人反感。
鉴于这些选择,我可能只是使用编译指示禁用该部分代码的-Wwrite-strings警告。
(您引用的其他代码,例如[LOG_QUIET] = "quiet"
,使用C99当前不支持的C99语法。[]=
语法允许您通过索引初始化数组成员。)