Pergunta

How do I get the option -10 from command line arguments- "tail -10". getopt function finds '1' character. But how do I access the string "10"?

If this can be done by getopt_long, an example would help. Thanks.

Foi útil?

Solução

Unless you intend for -1 to be an option with 0 as its argument, the answer is you don't. getopt is only made for processing options that fit the standard POSIX utilities' option syntax. It may be possible to use GNU getopt_long for this purpose, or you could just write your own argv parser (it's easy).

Edit: Actually I think I misread what you want. If you want - followed by any number to be interpreted as an option with that numeric value, I don't think there's any version of getopt that will work. There's no way you can special-case every single number as an option, and if you simply tell getopt that all of the digits are option characters that take arguments, -123 will be interpreted as a -1 option with an argument of 23 (which is fine, you can interpret it from there), but a lone -1 will cause the next argv element to get eaten as an argument to -1, which is difficult or impossible to recover from.

Outras dicas

What is going on here is that c the language comes with absolutely no standard about the proper way to handle command line options.

Moreover, the unix world had no such standard for quite some time ( believe there is a whole section about it in the Unix Haters Handbook (PDF link)).

So, people wrote ad hoc handling mechanisms. These eventually evolved toward a common(ish) standard and getopt was born (at Bell labs). Later we got the GNU getopt and getopt_long. These are not required, however, and some programs still manage things their own way.

But before things settled down (and occasionally after), people added new features to the "usual" way of handling options whenever they seemed like a good idea. Now, it's a pretty good bet that tail will want to have the number of lines adjusted more often than any other feature, so making it easy and few keystrokes to adjust must have seemed like a good idea at the time...

I never did like getopt that much, so I did the usual thing and reinvented the wheel. I call my solution argopt. You can get the source and manual page at https://github.com/colding/argopt. It is, I think, much easier to use than getopt.

Where possible, I would recommend changing the command argument syntax to avoid numeric arguments, either by passing the number as an option argument (e.g. -n -5) or allowing it only after the -- option delimiter.

For cases where changing the argument syntax is not possible, the BUGS section of the BSD getopt(3) man page documents a way to do this. I've adjusted their solution to avoid optreset, which is not specified by POSIX and not supported by glibc:

int ch;
long num;
char *numarg;

while ((ch = getopt(argc, argv, "0123456789")) != -1) {
    switch (ch) {
    case '0': case '1': case '2': case '3': case '4':
    case '5': case '6': case '7': case '8': case '9':
        numarg = argv[optind - 1];
        if (numarg[0] == '-' && numarg[1] == ch && numarg[2] == '\0') {
            num = '0' - ch;
        } else if ((numarg = argv[optind]) != NULL && numarg[1] == ch) {
            char *ep;
            int numoptind = optind;

            num = strtol(numarg, &ep, 10);
            if (*ep != '\0') {
                fprintf(stderr, "illegal number -- %s\n", numarg);
                return EXIT_FAILURE;
            }

            /* Advance getopt internal state to next argument. */
            while (optind == numoptind) {
                ch = getopt(argc, argv, "0123456789");
                assert(ch >= '0' && ch <= '9');
            }
        } else {
            fprintf(stderr, "number after other options -- %s\n", numarg);
            return EXIT_FAILURE;
        }
        break;

    default:
        /* Unrecognized option character.  Error printed by getopt. */
        return EXIT_FAILURE;
    }
}

You can replace getopt with getopt_long and add additional short or long options as necessary.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top