getopt 命令行获取值 C++

getopt command line get values c++

本文关键字:C++ 获取 命令行 getopt      更新时间:2023-10-16

你如何在getopt中获取标志的值,我尝试过谷歌搜索它,但我得到的只是如何切换大小写和设置标志。我得到了下面的代码,我想做的是有三个标志,-a、-b、-c,但只有两个标志像./filename -a somevalue -c anothervalue一样传递,或者./filename -b somevalue -c anothervalue有任何帮助吗?

int main(int argc, char *argv[])
{
   int flagA = 0;
   int flagB = 0;
   while (1) {
    char c;
    c = getopt (argc, argv, "abc:");
    if (c == -1) {
        break;
    }
    switch (c) {
    case 'a':
        flagA = 1;
         //cout<<optarg<<endl; //I tried printing the value but it only prints the second  flag value
        break;
    case 'b':
        flagB = 1;
        cout<<optarg<<endl;
        break;
    case 'c':
        cout<<optarg<<endl;
        break;
   case '?':
    default:
       cout<<"Usage: %s [-a] [-b <something>].n", argv[0]<<endl;
    }
   if(flagA > 0){
    //do something using the values of flagA and flagC 
   }
   else if(flagB > 0){
      //do something using the values of flagB and flagC
   }
 }
 return 0;
 }

如果您打算将optarg与标志一起使用,则在选项字符串中,该标志必须在它后面有:

        c = getopt(argc, argv, "a:b:c:");

您的用法输出语句不应为您编译。此外,您正在尝试将 C 样式格式说明符混合到C++输出流中,这是不正确的。

            cout << "Usage: " << argv[0] << " [-a] [-b <something>].n";

代码存在多个问题,但关键在于您对getopt()的调用。 你有选项控制字符串"abc:",这意味着-a-b都不采用选项。

假设您使用的是 POSIX 标准版本的 getopt() 而不是 GNU getopt(),那么当您运行任一时:

./filename -a somevalue -c anothervalue
./filename -b somevalue -c anothervalue

第一个标志之后的somevalue表示选项已完成,其余参数是非选项参数。 GNU getopt(),在没有环境变量POSIXLY_CORRECT的情况下,将排列参数列表,以便-c anothervalue也被识别(并且参数被排列,使得somevalue最终在最后(。

你的代码会写得更好:

#define _XOPEN_SOURCE 600 
#include <iostream>
#include <unistd.h>
using namespace std;
int main(int argc, char *argv[])
{
    int flagA = 0;
    int flagB = 0;
    int opt;
    char *c_opt = 0;
    while ((opt = getopt(argc, argv, "abc:")) != -1)
    {
        switch (opt)
        {
        case 'a':
            flagA = 1;
            cout << "A: " << flagA << "n";
            break;
        case 'b':
            flagB = 1;
            cout << "B: " << flagB << "n";
            break;
        case 'c':
            c_opt = optarg;
            cout << "C: " << c_opt << "n";
            break;
        default:
            cerr << "Usage: " << argv[0] << " [-a] [-b] [-c <something>]n";
            return -1;
        }
    }
    if (flagA)
    {
        // do something using the values of flagA and c_opt (if set)
    }
    else if (flagB)
    {
        // do something using the values of flagB and c_opt (if set)
    }
    else if (c_opt)
    {
        // do something using just c_opt (neither flagA nor flagB is set)
    }
    else
    {
        // do something if no options are specified (report error?)
    }
    for (int i = optind; i < argc; i++)
        cout << "File: " << i << ": " << argv[i] << "n";
    return 0;
}

上面的代码(经修订(在Mac OS X 10.10(优胜美地(上使用GCC 4.9.1进行了干净的编译:

g++ -O3 -g -std=c++11 -Wall -Wextra -Werror opt.cpp -o opt

BSD风格的getopt()接近POSIX标准,所以我得到的结果是:

$ ./opt -a 5 -c something
A: 1
File: 2: 5
File: 3: -c
File: 4: something
$

florw.wat 评论道:

我希望-a-b选项接受论点。我想做的是我有两个函数,它们接受两个参数,所以如果设置了-a那么我想调用函数a否则-b然后调用函数b。我需要这两个值来调用函数。

鉴于该说明,代码可能如下所示:

#define _XOPEN_SOURCE 600
#include <cstdlib>
#include <iostream>
#include <unistd.h>
using namespace std;
static void usage(const char *arg0)
{
    cerr << "Usage: " << arg0 << " [-a filename | -b filename] -c <something>n";
    exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
    char *a_opt = 0;
    char *b_opt = 0;
    char *c_opt = 0;
    int opt;
    while ((opt = getopt(argc, argv, "a:b:c:")) != -1)
    {
        switch (opt)
        {
        case 'a':
            a_opt = optarg;
            cout << "A: " << a_opt << "n";
            break;
        case 'b':
            b_opt = optarg;
            cout << "B: " << b_opt << "n";
            break;
        case 'c':
            c_opt = optarg;
            cout << "C: " << c_opt << "n";
            break;
        default:
            cerr << "Unknown option: " << optopt << "n";
            usage(argv[0]);
            break;
        }
    }
    if (optind != argc || c_opt == 0 || (a_opt && b_opt) || (a_opt == 0 && b_opt == 0))
        usage(argv[0]);
    else if (a_opt)
        cout << "A&C: " << a_opt << " " << c_opt << "n";
    else
        cout << "B&C: " << b_opt << " " << c_opt << "n";
    return 0;
}

示例运行:

$ ./opt -a option -c something
A: option
C: something
A&C: option something
$