Getopt - 为缺少的选项和缺少的非选项参数添加大小写

Getopt - adding case for both missing option and missing non-option argument

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

例如:

fizzle.exe -a textfile.txt 按照选项 -a

规定的方式读取 textfile.exe

fizzle.exe -a 以选项 a

规定的方式读取标准输入

我还没有开始工作的是:

fizzle.exe textfile.txt 读取 textfile.txt(如果没有正确的文本文件,则为标准输入)按照不提供选项[=]规定的方式11=]

这是我的代码:

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;          

    }
}

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

使用 getopt 的程序应该按照惯例从标准输入读取,如果你给它一个 - 作为输入参数。

附带说明一下,您应该始终为 ?(或 default 案例)准备一个案例。

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

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

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

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

好吧,你完全可以用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 选项实现上述逻辑的简短示例。最后一个case也指定了,如果给定,也将给定所有选项后第一个未处理的选项作为读取的文件名。

#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;
}

例子Use/output

$ ./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

仔细阅读,如果您有任何问题,请告诉我。