带有“getopt”的分段错误

Segmentation Fault with `getopt`

本文关键字:分段 错误 getopt 带有      更新时间:2023-10-16

我有一个处理参数两个三个全局变量的函数。它适用于program -s3,但是如果我在s和参数之间放置一个空格,即使我使用 atoi 删除空格,我也会出现分段错误。

这是代码:

bool handleArgs(int argc, char *argv[])
{
    int arg;
    bool rtVal = true;
    while (true)
    {
        static struct option long_options[] =
             {
               {"steps",             optional_argument, 0, 's'},
               {"walks",         optional_argument, 0, 'w'},
               {"dimensions",  optional_argument, 0, 'd'},
               {nullptr, 0, 0, 0}
             };
        int option_index = 0;
        arg = getopt_long (argc, argv, "s::w::d::",long_options, &option_index);
    if(arg == -1)
        {
            break;
        }

        switch(arg)
        {
         case 0:
                     std::cout << long_options[option_index].name  << std::endl;
                     if (optarg)
                         std::cout << " with arg " << optarg << std::endl;
                     break;
            case 's':
                    std::cout << "option -s with value " << atoi(optarg) << std::endl;
                break;
            case 'w':
                    std::cout << "option -w with value " << atoi(optarg) << std::endl;
                break;
            case 'd':
                    std::cout << "option -d with value " << atoi(optarg) << std::endl;
                    break;
            case '?':
                /* getopt_long already printed an error message. */
                rtVal = false;
                break;
            default:
            rtVal = false;
        }
    }
    return rtVal;
}

-s 的处理程序中,您不检查optarg为 0。但是您在选项字符串中s后指定两个冒号:(来自man 3 getopt):

两个冒号表示一个选项需要一个可选的参数;如果当前 argv-element 中有文本(即,与选项名称本身使用相同的单词,例如"-oarg"),则以 optarg 返回,否则optarg设置为零。 这是一个 GNU 扩展。

当 shell 在调用 program -s 3 后启动程序时,它会在 argv 向量中提供三个元素:

0: program
1: -s
2: 3

通常,getopt会将其解释为与调用program -s3相同,并且很难看到更改此行为的理由。但是,gnu 为您提供了这样的选项,允许您将program -s 3解释为没有参数和位置参数3-s选项。一旦你走上这条路,你必须在尝试使用它之前检查optarg是否0

我怀疑你并不是真的想启用这个 gnu 扩展。很少有应用程序会从中受益。