0

我正在编写一些代码来解析命令行输入。我使用 getopt_long 的方式如下:

int c = 0; 
static struct option long_options[] =  
{ 
    {"mode",        1,  NULL,   'm'}, 
    {"help",        0,  NULL,   'h'}, 
    {0,             0,  0,      0} 
}; 
while ((c = getopt_long(argc, argv, "mh", long_options, NULL))!=-1) 
{ 
    switch(c) 
    { 
        case 0: 
        { 
            cerr<<"Usage: ./program <-m> <-h>"<<endl; 
            exit(1); 
            break; 
        } 
        case 'm': 
        { 
            if (!strcmp(optarg, "small"))
                mode = 0;
            else if (!strcmp(optarg, "medium"))
                mode = 1;
            else if (!strcmp(optarg, "large"))
                mode = 2;
            else{
                cerr<<"Invalid mode "<<optarg<<endl;
                exit(1);
            }
            break; 
        } 
        case 'h': 
        { 
            cerr<<"See man page for help."<<endl;
            exit(0); 
        } 
        default: 
        { 
            cerr<<"Unrecognized argument!"<<endl; 
            exit(1); 
        } 
    } 
}

我测试了以下内容:

1)

./program

程序不进入while循环。检查变量 c 为 -1。

2)

./program -h

效果很好。

3)

./program -m small

程序退出并从 strcmp() 抛出分段错误。

谢谢你的帮助。

4

1 回答 1

1

这是一个如何解析选项getopt_long()并正确处理其返回值的示例,例如选项结束、缺少参数和未知选项:

struct Options
{
    std::string username = "guest";

    void parse_command_line(int ac, char** av) try {
        enum {
              HELP
            , USER
        };

        // This array must be in the same order as the enum.
        option const options[] = {
              {"help",            no_argument, nullptr, HELP}
            , {"username",  required_argument, nullptr, USER}
            , {}
        };

        ::opterr = 0;
        for(int c; -1 != (c = getopt_long(ac, av, ":h", options, nullptr));) {
            switch(c) {
            // both short and long option
            case 'h':
            case HELP:
                usage(av, EXIT_SUCCESS);
                break;

            // only long option
            case USER:
                username = ::optarg; // 
                break;

            case ':': // missing argument
                throw Exception("--%s: an argument required", options[::optopt].name);

            case '?': // unknown option
                throw Exception("%s: unknown option", av[optind - 1]);
            }
        }

    }
    catch(std::exception& e) {
        fprintf(stderr, "error: %s\n", e.what());
        usage(av, EXIT_FAILURE);
    }
};

请注意,没有必要为每个多头期权设置相应的空头期权。

于 2012-11-26T09:21:32.810 回答