【问题标题】:C/C++ getopt optstring syntaxC/C++ getopt optstring 语法
【发布时间】:2012-11-07 00:39:50
【问题描述】:

在 C++ 中使用 unistd.h 中包含的 getopt 函数,有没有办法构造 optstring 使得...

[-a] [-f "reg_expr"] out_file1 [[-f "reg_expr"] out_file2 ...] 可以吗?

这是一个家庭作业,但重点不是这个特定的子任务。

在我的脑海中,我想指定以下逻辑:

(一个参数),(无限多个 f 参数和 2 个必需的(子)参数),...(无限多个通用参数)

也许我对getopt 函数的理解存在根本缺陷。我还看到了getopt_long。也许这就是我所缺少的。

我最初起草了这个,它工作,但我遇到了getopt 函数,并认为它可能会做得更好。

int outFileFlags;
int outFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
int i = 1;
while (i < argc){
    if (i == 1 && strcmp( argv[i], "-a") == 0){
        cout << "append flag set" << endl;
        outFileFlags = O_RDWR | O_APPEND;
        i++;
        continue;
    }
    else {
        outFileFlags = O_TRUNC | O_RDWR | O_CREAT;
    }
    if (strcmp( argv[i], "-f") == 0 && i+2 <= argc){
        cout << "   regx = " << argv[i+1] << endl;
        cout << "   fn = " << argv[i+2] << endl;
        i = i+3;
        continue;
    }
    else {
        cout << "   regx = none" << endl;
        cout << "   fn = " << argv[i] << endl;
        i++;
        continue;
    }
}

注意:假设这是为 unix 环境编写的。我不认为我可以使用标准库中的任何东西。我只包含 std::cout 用于测试目的。

我很乐意详细说明这项任务的任何细节。然而,主要问题围绕着 optstring 的语法。我目前只知道 : 表示必需和 :: 表示可选有没有办法指定像正则表达式通配符 * 一样重复的参数?

编辑:

我确信这是草率的,因为我不认为 getopt 旨在处理每个选项的多个参数,但它确实可以解决问题...

int main(int argc, char *argv[]){
    char c;
    int iterations = 0;
    while (*argv) {
        optind = 1;
        if (iterations == 0){
            opterr = 0;
            c = getopt(argc, argv, "a");
            if(c == 'a'){
                //~ APPEND SET
            }
            else if(c=='?'){
                optind--;
            }
        }
        while ((c = getopt(argc, argv, "f:")) != -1) {
            if (c == 'f'){
                //~ REGEX = optarg
                if (optind < argc && strcmp(argv[optind], "-f") != 0) {
                    //~ FILENAME = argv[optind]
                    optind++;
                }
                else {
                    errno = 22;
                    perror("Error");
                    exit(errno);
                }
            }
            else {
                errno = 22;
                perror("Error");
                exit(errno);
            }
        }
        argc -= optind;
        argv += optind;
        iterations++;
        //~ REMAINING FILES = *argv
    }
}

【问题讨论】:

    标签: c++ c unix command-line-arguments getopt


    【解决方案1】:

    您需要为每组选项和输出文件名执行单独的 getopt 循环。

    group_index = 0;
    while (*argv) {
      optreset = 1;
      optind = 1;
      while ((ch = getopt(argc, argv, "af:")) != -1) {
        switch (ch) {
          /* process options */
        }
      }
      argc -= optind;
      argv += optind;
      outfile[group_index++] = *argv;
      argc--;
      argv++;
    }
    

    【讨论】:

    • 我认为这不适用于 GNU getopt,它默认重新排列 argv 向量以允许处理尾随选项。您可以将“+”指定为参数说明符的第一个字符,或设置名称奇特的环境变量 POSIXLY_CORRECT 以获得符合 Posix 的行为。
    • argc -= optind; argv += optind; outfile[group_index++] = *argv; argc--; argv++; 这部分我不明白。你能解释一下它在做什么吗?另外,我在这里看不到 optreset :gnu.org/software/libc/manual/html_node/… 这是做什么的?
    • 在每组选项和输出文件名之后,它会更新argv指向剩余的参数,argc是剩余参数的计数,这样你就可以再次调用getopt来处理它们。 getopt 只理解在文件名之前包含所有选项的约定。我写的只是 getopt 手册页中示例的一个小变体。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-17
    相关资源
    最近更新 更多