使用getopt触发所有情况

时间:2016-02-18 17:26:05

标签: c getopt

我正在尝试使用getopt,以便根据给定的参数运行两个不同的函数。

int main(int argc, char **argv) {
    int i;
    int identify;
        while ((identify = getopt(argc, argv, "c:")) != -1) {
            switch (identify) {
                case 'c':
                    for (i = 2; i < argc; i++) {
                        readerC(argv[i]);
                    }
                default:
                    for (i = 2; i < argc; i++) {
                        reader(argv[i]);
                    }
            }
        }
    return(0);
}

目的是,如果命令包含“-c”,那么它将运行“readerC”函数。如果没有传递参数,那么它将读取“阅读器”功能。

我多次修改了上面的函数,但是在运行没有参数的命令(没有输出)时,我似乎无法运行“reader”函数。以前,输入-c会根据需要运行readerC命令,但是在搞乱之后,它现在运行readerC函数,然后是reader函数。

我尝试将“default:”更改为“case”:“”和“case”?'“但这也没有用。任何帮助将不胜感激:)

2 个答案:

答案 0 :(得分:2)

您忘记添加break语句。如果没有break,控件只会落到下一个案例中。以下是将break语句插入相关位置的代码:

while ((identify = getopt(argc, argv, "c:")) != -1) {
    for (i = 2; i < argc; i++) {
        switch (identify) {
            case 'c':
                for (i = 2; i < argc; i++) {
                    readerC(argv[i]);
                }
                break;
            default:
                for (i = 2; i < argc; i++) {
                    reader(argv[i]);
                }
                break; /* not really needed but for completeness */
        }
    }
}

此外,您似乎对所有嵌套循环使用相同的i。你确定那是你想要的吗?您可能还想查看optarg变量,该变量指向与当前解析选项对应的参数。

也许还会读到getopt如何再次运作,因为看起来你还没有完全理解它。你写的这些循环有些奇怪。

答案 1 :(得分:0)

main()程序处理选项的顺序通常是:

  • 初始化
  • 选项解析
  • 做真正的工作

您应该使用getopt()处理选项,然后处理文件参数。您还需要在break语句中加入switch,因为C不会在案例之间自动中断。

因此,您最终可能会:

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

static void reader(const char *file);
static void readerC(const char *file);

int main(int argc, char **argv)
{
    void (*function)(const char *arg) = reader;
    int opt;
    while ((opt = getopt(argc, argv, "c")) != -1)
    {
        switch (opt)
        {
        case 'c':
            function = readerC;
            break;
        default:
            fprintf(stderr, "Unrecognized option %c\n", optopt);
            exit(1);
        }
    }

    if (optind == argc)
    {
        fprintf(stderr, "Usage: %s [-c] file ...\n", argv[0]);
        exit(1);
    }

    for (int i = optind; i < argc; i++)
    {
        (*function)(argv[i]);   // The old-fashioned way
        // function(argv[i]);   // The more modern way
    }

    return(0);
}

如果你对函数指针感到不舒服,那么你可以使用一个标志:

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

static void reader(const char *file);
static void readerC(const char *file);

int main(int argc, char **argv)
{
    int cflag = 0;
    int opt;
    while ((opt = getopt(argc, argv, "c")) != -1)
    {
        switch (opt)
        {
        case 'c':
            cflag = 1;
            break;
        default:
            fprintf(stderr, "Unrecognized option %c\n", optopt);
            exit(1);
        }
    }

    if (optind == argc)
    {
        fprintf(stderr, "Usage: %s [-c] file ...\n", argv[0]);
        exit(1);
    }

    for (int i = optind; i < argc; i++)
    {
        if (cflag)
            readerC(argv[i]);
        else
            reader(argv[i]);
    }

    return(0);
}