【问题标题】:Getopt - adding case for both missing option and missing non-option argumentGetopt - 为缺少的选项和缺少的非选项参数添加案例
【发布时间】:2016-04-27 20:37:51
【问题描述】:

我正在制作一个更大程序的一部分,这部分从文本文件或标准输入提要中获取信息,这些信息的性质取决于添加到程序中的选项。没有添加文本文件作为非选项参数,程序应该从标准输入读取。

例如:

fizzle.exe -a textfile.txt 以选项 -a 规定的方式读取 textfile.exe

fizzle.exe -a 以选项 a 规定的方式读取标准输入

我还没开始工作的是:

fizzle.exe textfile.txt 以不提供选项规定的方式读取 textfile.txt(或 stdin,如果没有适当的文本文件)

这是我的代码:

while ((option = getopt(argc,argv, ":a:b:")) != -1 ) {

    FILE *pointerFile = filereader(optarg);

    switch(option) {
        case 'a' :
            optionchosen = 0;
            counter(optionchosen,pointerFile,argv);
            break;

        case 'b' :
            optionchosen = 1;
            counter(optionchosen,pointerFile,argv);
            break;


        case ':' :
            counter(optionchosen,pointerFile,argv);
            break;          

    }
}

我不知道如何向这个开关添加一个案例,该开关通过不提供任何选项来激活,但在有或没有非选项参数(文件名)的情况下仍然有效。

【问题讨论】:

  • 您能否以一种看起来不像文件名 jive 的格式良好的方式发布特定问题? brackets.exe的作用是什么?
  • 我清理了,希望对您有所帮助。文本文件提供了一些计算所需的信息。阅读和计算都完美无缺。我没有详细说明该文件的作用,因为我觉得这会浪费时间、混淆和分散问题的注意力。

标签: c getopt


【解决方案1】:

嗯,你可以用getopt 做你想做的事,而且你只需要稍微调整你的逻辑。具体来说,您可以设置getopt 以便:

fizzle.exe                        /* reads from stdin   */
fizzle.exe -a                     /* reads from stdin   */
fizzle.exe -a textfile.txt        /* reads textfile.txt */
fizzle.exe textfile.txt           /* reads textfile.txt */

这是一个围绕-a 选项实现上述逻辑的简短示例。最后一种情况还指定,如果给定,则在给定所有选项后第一个未处理的选项也将作为要读取的文件名。

#include <stdio.h>
#include <unistd.h> /* for getopt */

int main (int argc, char **argv) {

    int opt;
    char *fn = NULL;
    FILE *pointerFile = stdin;  /* set 'stdin' by default */

    while ((opt = getopt (argc, argv, "a::b:")) != -1) {
        switch (opt) {
            case 'a' :  /* open file if given following -a on command line */
                if (!optarg) break;     /* if nothing after -a, keep stdin */
                fn = argv[optind - 1];
                pointerFile = fopen (fn, "r");
                break;
            case 'b' :; /* do whatever */
                break;
            default :   /* ? */
                fprintf (stderr, "\nerror: invalid or missing option.\n");
        }
    }
    /* handle any arguments that remain from optind -> argc
     * for example if 'fizzle.exe textfile.txt' given, read from
     * textfile.txt instead of stdin.
     */
    if (pointerFile == stdin && argc > optind) {
        fn = argv[optind++];
        pointerFile = fopen (fn, "r");
    }

    printf ("\n fizzle.txt reads : %s\n\n", pointerFile == stdin ? "stdin" : fn);

    return 0;
}

示例使用/输出

$ ./bin/optfizzle

 fizzle.exe reads : stdin

$ ./bin/optfizzle -a

 fizzle.exe reads : stdin

$ ./bin/optfizzle -a somefile.txt

 fizzle.exe reads : somefile.txt

$ ./bin/optfizzle someotherfile.txt

 fizzle.exe reads : someotherfile.txt

查看一下,如果您有任何问题,请告诉我。

【讨论】:

  • 我删除了我自己解决的两个问题。感谢您提供这个干净的解决方案,我了解它是如何解决我的问题的,并且我已经对其进行了编辑以适合我的程序(文件读取和计算是分开完成的):)
【解决方案2】:

忘记 getopt 字符串中的前导 :;只需使用 getopt 作为选项。完成后,命令行上的其余元素(如果有)位于argv[optind]argv[argc] 之间。

如果调用者未提供文件名,则使用 /dev/stdin 作为默认值,或使用 stdlib.h 中的 stdin。无需要求用户提供- 来代替标准输入。

【讨论】:

    【解决方案3】:

    如果您将- 作为输入参数,则按照惯例,使用getopt 的程序应该从标准输入读取。

    附带说明一下,您应该始终拥有? 的案例(或default 的案例)。

    这是读取剩余参数的示例,将其放在处理所有 getopt 标志的大 while 循环下方:

    int i;
    for (i = optind; i < argc; ++i)
        printf("Non-option argument %s\n", argv[i]);
    

    【讨论】:

    • 好的。但是有没有一个案例我可以添加到程序中让它按照我想要的方式工作而没有 -?
    • 通常getopt仅用于开关,文件名通常取自getopt未解析的剩余参数。
    • 哦,这很有趣。
    • @Flowdorio man getopt 将对此进行更详细的描述。
    • 您有任何示例说明如何在不包含文件名作为 optarg 的情况下执行此操作吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-27
    • 2015-02-25
    • 2022-09-22
    • 1970-01-01
    相关资源
    最近更新 更多