使用 getopt 一次触发所有情况

Using getopt triggers all cases in one

我正在尝试使用 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" 函数。

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

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

您忘记添加 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 的工作原理,因为您似乎还不太了解它。你写的这些循环有点奇怪。

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

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

您应该使用 getopt() 处理选项,然后处理文件参数。您还需要在 switch 语句中包含 break,因为 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);
}