C中有多个命令行参数

时间:2015-01-18 20:49:44

标签: c switch-statement command-line-arguments getopt

我想知道处理多个命令行参数的最佳方法。我看过用switch和case语句完成命令行参数,如下所示:

while ((x = getopt(argc, argv, "bic:")) != -1){
switch (x){
  case 'b':
    //do something
    break;
  case 'i':
    //do something
    break;
  case 'c':
    //do something
    break;  
  default:
    break;
}

这很好用。但是,它不适合使用多个命令行参数。对于我正在进行的项目,如果我输入多个参数,我希望这是两种情况的组合,如果这有意义的话。因此,案例之间的划分有点烦人......我想我可以为每个组合制作单独的案例,例如case: 'ib'case: 'ibc' 但是有更简单的解决方案吗?

另外,我试图找到一个解决方案,它与输入的参数顺序无关。 a.out -b -c应与a.out -c -b

相同

1 个答案:

答案 0 :(得分:0)

根据我的评论,我希望代码看起来像这样。目前尚不清楚你为什么要c参与辩论。

int main(int argc, char **argv)
{
    int opt;
    int i_flag = 0;
    int b_flag = 0;
    int c_flag = 0;

    while ((opt = getopt(argc, argv, "bci")) != -1)
    {
        switch (opt)
        {
        case 'b':
            b_flag = 1;
            break;
        case 'c':
            c_flag = 1;
            break;
        case 'i':
            i_flag = 1;
            break;
        default:
            fprintf(stderr, "Usage: %s [-bci] [file ...]\n", argv[0]);
            exit(EXIT_FAILURE);
        }
    }

    if (optind < argc)
    {
        for (int i = optarg; i < argc; i++)
        {
            FILE *fp = fopen(argv[i], "r");
            if (fp == 0)
                fprintf(stderr, "%s: failed to open file %s\n", argv[i]);
            else
            {
                process_file(fp, argv[i], b_flag, c_flag, i_flag);
                fclose(fp);
            }
        }
    }
    else
    {
        process_file(stdin, "-", b_flag, c_flag, i_flag);
    }
    return 0;
}

警告:未编译的代码。

process_file()函数的签名如下:

void process_file(FILE *fp, const char *fn, int b_flag, int c_flag, int i_flag);

如果要重写文件,则必须决定是否处理标准输入(无文件名),如果是,则必须如何处理。如果您只是将新文件写入标准输出,那么也很容易处理标准输入。

您可以修改代码,以便检测process_file()是否成功(例如,它返回一个整数而不是void)并根据是否所有文件都修改程序的退出状态处理成功。您可以确定您的函数不需要文件名(这样就不必为标准输入指定"-""/dev/stdin"等名称。

您可以将标志转换为全局变量,process_file()函数可以对每一行应用适当的转换。您可以决定对每个文件执行多次转换,在每次转换之间打开和关闭文件,或者如果您愿意,可以在每次转换之间倒回文件。但是,这比并行执行三个变换要慢。

GNU版本getopt()提供参数排列,以便您可以执行:

program -b -c -i name-of-file
program name-of-file -b -c -i
program -b name-of-file -i -c

他们都会一样工作(你仍然使用上面的代码)。就个人而言,我不喜欢这样,但我很老套。如果您小心,可以将其关闭 - 一种方法是通过POSIXLY_CORRECT环境变量。您还可以安排getopt()返回文件,就好像它们是带有选项代码'\1' Control-A )的参数一样。