我能得到的最简单的getopt程序?

时间:2013-09-01 02:57:37

标签: c command-line-arguments gnu getopt

在对此link进行了一些关于如何使用getopt()的阅读之后,我试图找一个小例子。

我想要的是:

./prog -v      # show me prog version
./prog -f filename  # just show me the filename I entered from the command line

这是我到目前为止所写的内容:

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

int
main(int argc, *argv[]) {
     char VER[] = "0.1.1";
     int opt;
     opt = getopt(argc, argv, "vf:");
     char *filename;

      while (opt != -1) {
           switch(opt) {
            case 'v':
                printf("version is %s", VER);
                break;
            case 'f':
                filename = optarg;
                break;
            }
     }
    printf("The filename was %s", filename);
    return 0;
}

我用以下代码编译代码:

$ gcc prog.c -o prog -Wall -Wextra

当我使用-v选项运行它时,我似乎无法理解它永远不会停止打印版本 并且-f filename它停在那里,从不打印我输入的文件名。

3 个答案:

答案 0 :(得分:3)

它不会因为您只调用getopt()一次而停止。一个可能的解决方法:

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

int
main(int argc, char **argv)
{
    char VER[] = "0.1.1";
    int opt;
    const char *filename = "unspecified";

    while ((opt = getopt(argc, argv, "vf:")) != -1)
    {
        switch (opt)
        {
            case 'v':
                printf("version is %s\n", VER);
                break;
            case 'f':
                filename = optarg;
                break;
            default:
                fprintf(stderr, "Usage: %s [-v][-f file]\n", argv[0]);
                return(1);
        }
    }
    printf("The filename was %s\n", filename);
    return 0;
}

请注意,我确保filename已初始化,printf()输出以换行符结束,并且报告了错误情况。

这是另一个稍微复杂的示例程序:

/* Example 1 - using POSIX standard getopt() */

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

int
main(int argc, char **argv)
{
    int opt;
    int i;
    int bflag = 0;
    int aflag = 0;
    int errflag = 0;
    char *ifile = 0;
    char *ofile = 0;

    while ((opt = getopt(argc, argv, ":abf:o:")) != -1)
    {
        switch (opt)
        {
        case 'a':
            if (bflag)
                errflag++;
            else
                aflag++;
            break;
        case 'b':
            if (aflag)
                errflag++;
            else
                bflag++;
            break;
        case 'f':
            ifile = optarg;
            break;
        case 'o':
            ofile = optarg;
            break;
        case ':':   /* -f or -o without operand */
            fprintf(stderr, "Option -%c requires an operand\n", optopt);
            errflag++;
            break;
        case '?':
        default:
            fprintf(stderr, "Unrecognized option: -%c\n", optopt);
            errflag++;
            break;
        }
    }

    if (errflag)
    {
        fprintf(stderr, "Usage: %s [-a|-b][-f in][-o out] [file ...]\n", argv[0]);
        exit(2);
    }

    printf("Flags: a = %d, b = %d\n", aflag, bflag);
    if (ifile != 0)
        printf("Input: %s\n", ifile);
    if (ofile != 0)
        printf("Output: %s\n", ofile);
    printf("Argc = %d, OptInd = %d\n", argc, optind);
    for (i = optind; i < argc; i++)
        printf("File: %s\n", argv[i]);
    return(EXIT_SUCCESS);
}

它基于Sun手册中的示例。 -a-b选项是互斥的。它说明了POSIX getopt()的限制,其中启用了“可选参数”(选项字符串上的前导:)。它还在最后打印出输入。

答案 1 :(得分:1)

下面:

case 'v':
    printf("version is %s", VER);
    break;

break让你脱离switch语句,而不是while循环,所以while循环继续,你继续,因为{{ 1}}永远不会改变。你错过了一些逻辑,在这里,你可能想在循环中的某个地方再次调用opt

答案 2 :(得分:1)

int main(int argc, *argv[], "vf")   


getopt.c:5:20: error: expected declaration specifiers or â...â before â*â token
getopt.c:5:28: error: expected declaration specifiers or â...â before string constant

这应该是

int main(int argc, char *argv[] )     

修改后的代码:

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

int main(int argc, char *argv[])
  {
     char VER[] = "0.1.1";
     int opt;
   opt = getopt(argc, argv, "vf:");
     char *filename;

      while (opt != -1) {
           switch(opt) {
            case 'v':
                printf("version is %s\n", VER);
                exit(0);
            case 'f':
             //   filename = optarg;
                 printf("The filename was %s\n", argv[2]);
                exit(0);


            }
     }
    return 0;