getopt无法识别c中的多个命令行标志

时间:2015-07-13 14:55:59

标签: c command-line-arguments getopt

我正在学习C,我正在尝试使用getopt()来获取命令行标志。我的问题是它只会将第一个命令标志识别为标志,并将其他任何标志视为常规命令行参数。这是我的代码:

#include <stdio.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char *argv[]) {
    char *delivery = "";
    int thick = 0;
    int count = 0;
    char ch;

    while ((ch = getopt(argc, argv, "d:t")) != -1) {
        switch (ch) {
            case 'd':
                delivery = optarg;
                break;
            case 't':
                thick = 1;
                break;
            default:
                fprintf(stderr, "Unknown option: '%s'\n", optarg);
                return 1;
        }
        argc -= optind;
        argv += optind;
    }
    if(thick) {
        puts("Thick crust.");
    }
    if (delivery[0]) {
        printf("To be delivered %s.\n", delivery);
    }
        puts("Ingredients:");
        for(count = 0; count < argc; count++) {
            if (!strstr(argv[count], "./")) {
                puts(argv[count]);
            }
        }
    return 0;
}

当我做一面旗帜或没有旗帜时,它完全正常:

$ ./order_pizza Anchovies
Ingredients:
Anchovies

$ ./order_pizza Anchovies Pineapple
Ingredients:
Anchovies
Pineapple

$ ./order_pizza -d now Anchovies Pineapple
To be delivered now.
Ingredients:
Anchovies
Pineapple

$ ./order_pizza -t Anchovies Pineapple
Thick crust.
Ingredients:
Anchovies
Pineapple

然而,当我做一个以上的旗帜时:

$ ./order_pizza -d now -t Anchovies Pineapple
To be delivered now.
Ingredients:
-t
Anchovies
Pineapple

$ ./order_pizza -t -d now Anchovies Pineapple
Thick crust.
Ingredients:
-d
now
Anchovies
Pineapple

我似乎无法弄清楚我做错了什么,因为从我的搜索中似乎没有人遇到同样的问题。我在Windows 7上使用cygwin并使用以下行编译:

$ gcc order_pizza.c -o order_pizza

有人有什么想法吗?

1 个答案:

答案 0 :(得分:1)

请勿修改argc循环内的argvwhile,并调用getopt。它使用这些变量来发挥它的魔力,所以改变它们会使它变得混乱。

所以不要这样:

while ((ch = getopt(argc, argv, "d:t")) != -1) {
    switch (ch) {
    ...
    }
    argc -= optind;
    argv += optind;
}

这样做:

while ((ch = getopt(argc, argv, "d:t")) != -1) {
    switch (ch) {
    ...
    }
}
argc -= optind;
argv += optind;