The simplest possible getopt program I can get?

扶醉桌前 提交于 2019-12-24 13:24:04

问题


After doing some reading on this link on how to use getopt(), I'm trying to get a small example.

What I want, is something like:

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

Here is what I wrote so far:

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

I compile the code with:

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

I can't seem to understand when I run it with -v option it never stops printing the version and with -f filename it stops there and never prints the filename I entered.


回答1:


It doesn't stop because you only call getopt() once. A possible fix:

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

Note that I've made sure that filename is initialized, that printf() outputs end with a newline, and that the error cases are reported.

Here's another, slightly more complex, example program:

/* 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);
}

It is based on an example from a Sun manual. The -a and -b options are mutually exclusive. It illustrates (the limitations of) POSIX getopt() with 'optional arguments' enabled (the leading : on the option string). It also prints out its inputs at the end.




回答2:


Here:

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

the break is breaking you out of the switch statement, not out of the while loop, so the while loop continues and you go on forever because opt never changes. You're missing some logic, here, you probably want to be calling getopt() again somewhere in the loop.




回答3:


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

this should be

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

modified code:

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


来源:https://stackoverflow.com/questions/18554775/the-simplest-possible-getopt-program-i-can-get

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!