简体   繁体   English

C:getopt():选项似乎无效

[英]C: getopt(): option does not seem to have effect

I am trying out the following C code (saved in file called testgetopt.c): 我正在尝试以下C代码(保存在名为testgetopt.c的文件中):

#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <ctype.h>

void usage(char *s)
{
    fprintf(stderr, "Usage: %s [-d] -i input-TIFF-file -o output-raw-file\n", s);
    fprintf(stderr, "Note: -d indicates debugging option\n");
}

int main(int argc, char **argv) { 
    char c;
    size_t i;
    char *itext = NULL, *otext = NULL;
    FILE *fout;
    short debug = 0;

    if ((c = getopt(argc, argv, "di:o:")) == EOF) {
        usage(argv[0]);
        exit(1);
    }

    while ((c = getopt(argc, argv, "di:o:")) != EOF) {
        switch (c) {
        case 'd':
            debug = 1;
            break;
        case 'i':
            itext = optarg;
            break;
        case 'o':
            otext = optarg;
            break;
        case '?':
            if (optopt == 'i' || optopt == 'o')
                fprintf (stderr, "Option -%c requires an argument.\n", optopt);
            else if (isprint (optopt))
                fprintf (stderr, "Unknown option `-%c'.\n", optopt);
            else
                fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
            usage(argv[0]);
            exit(1);
        default:
            fprintf(stderr, "Both -i and -o are needed\n");
            usage(argv[0]);
            exit(1);
        }
    }
    printf("debug = %i\n", debug);
    if (debug) 
        printf ("input file = %s, output file = %s\n", itext, otext);
    return EXIT_SUCCESS;
}

I compile using: 我编译使用:

gcc testgetopt.c 

But regardless of whether I include -d or not, I always get debug set at 0. The program should have -d set debug at 1, 0 otherwise. 但是,无论是否包含-d,我总是将调试设置为0。否则,程序应将-d调试设置为1,否则为0。

What is being done wrong? 做错了什么?

Here are the examples: 以下是示例:

Let us first try with no -d 让我们先尝试一下-d

./a.out -i in.dat -o out.dat
debug = 0

Let us next try with -d included. 让我们接下来尝试使用-d。

./a.out -d -i in.dat -o out.dat
debug = 0

Thank you in advance for any help and suggestions! 预先感谢您的任何帮助和建议!

The problem is that you are calling getopt as a sanity check and then not using its result when it succeeds. 问题是您将getopt称为完整性检查,然后在成功时不使用其结果。 That means the first option is always discarded. 这意味着第一个选项总是被丢弃。 You can easily verify this by putting -d as a non-first option: 您可以通过将-d作为非第一选项来轻松验证这一点:

$ ./a.out -i in.dat -o out.dat -d
debug = 1
input file = (null), output file = out.dat

You can see that the -d did take effect this time but the first argument, -i , is not set. 您可以看到-d这次确实生效了,但是没有设置第一个参数-i

There are several ways to fix this. 有几种方法可以解决此问题。 The recommended way (IMHO) is to remove the first getopt call. 推荐的方法(IMHO)是删除第一个getopt调用。 Then change the sanity check to verify the actual options. 然后更改完整性检查以验证实际选项。 That is, there should be code after the getopt loop which verifies that all mandatory options have been provided. 也就是说,在getopt循环之后应该有代码来验证是否已提供所有必需的选项。

For example: 例如:

int main(int argc, char **argv) { 
    char c;
    size_t i;
    char *itext = NULL, *otext = NULL;
    FILE *fout;
    short debug = 0;

    /* REMOVED THIS BLOCK OF CODE
    if ((c = getopt(argc, argv, "di:o:")) == EOF) {
        usage(argv[0]);
        exit(1);
    }
    */

    while ((c = getopt(argc, argv, "di:o:")) != EOF) {
        switch (c) {
        case 'd':
            debug = 1;
            break;
        case 'i':
            itext = optarg;
            break;
        case 'o':
            otext = optarg;
            break;
        case '?':
            if (optopt == 'i' || optopt == 'o')
                fprintf (stderr, "Option -%c requires an argument.\n", optopt);
            else if (isprint (optopt))
                fprintf (stderr, "Unknown option `-%c'.\n", optopt);
            else
                fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
            usage(argv[0]);
            exit(1);
        default:
            fprintf(stderr, "Both -i and -o are needed\n");
            usage(argv[0]);
            exit(1);
        }
    }

    /* ADD SOME ARGUMENT SANITY CHECKS */
    if (!itext || !otext) {
        printf("Missing mandatory arguments\n");
        exit(1);
    }

    printf("debug = %i\n", debug);
    if (debug) 
        printf ("input file = %s, output file = %s\n", itext, otext);
    return EXIT_SUCCESS;
}

Because you are calling getopt twice, you need to reset optind = 1; 由于您两次调用getopt ,因此需要将optind = 1;重置optind = 1; ,请重新设置optind = 1; between the calls. 在通话之间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM