【问题标题】:Proper use of array of const char* in getsubopt在 getsubopt 中正确使用 const char* 数组
【发布时间】:2013-12-21 14:49:33
【问题描述】:

我正在尝试使用 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}; 的上下文中。

我曾尝试在网上其他地方寻找类似的构造,但没有找到任何可以帮助我解决这个问题的东西。我希望我在尝试尽可能清楚地提出问题时不要过于冗长。

【问题讨论】:

    标签: arrays pointers enums char constants


    【解决方案1】:

    您的代码是正确的。 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",使用 C++ 目前不支持的 C99 语法。[]= 语法允许您按索引初始化数组的成员。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-10
      • 2021-12-15
      • 2010-12-14
      • 2017-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-01
      相关资源
      最近更新 更多