C: getopt(): 选项似乎没有效果
C: getopt(): option does not seem to have effect
我正在尝试以下 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;
}
我编译使用:
gcc testgetopt.c
但是无论我是否包含 -d,我总是将调试设置为 0。程序应该将 -d 设置为 1,否则为 0。
哪里做错了?
示例如下:
让我们先试试没有-d
./a.out -i in.dat -o out.dat
debug = 0
接下来让我们尝试包含 -d。
./a.out -d -i in.dat -o out.dat
debug = 0
提前感谢您的帮助和建议!
问题是您调用 getopt
作为完整性检查,然后在成功时不使用其结果。这意味着第一个选项总是被丢弃。您可以通过将 -d
作为非第一选项来轻松验证这一点:
$ ./a.out -i in.dat -o out.dat -d
debug = 1
input file = (null), output file = out.dat
可以看到这次-d
确实生效了,但是第一个参数-i
没有设置。
有几种方法可以解决这个问题。推荐的方法(恕我直言)是删除第一个 getopt
调用。然后更改完整性检查以验证实际选项。也就是说,在 getopt
循环之后应该有代码验证是否已提供所有强制选项。
例如:
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;
}
因为您正在调用 getopt
两次,所以您需要在两次调用之间重置 optind = 1;
。
我正在尝试以下 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;
}
我编译使用:
gcc testgetopt.c
但是无论我是否包含 -d,我总是将调试设置为 0。程序应该将 -d 设置为 1,否则为 0。
哪里做错了?
示例如下:
让我们先试试没有-d
./a.out -i in.dat -o out.dat
debug = 0
接下来让我们尝试包含 -d。
./a.out -d -i in.dat -o out.dat
debug = 0
提前感谢您的帮助和建议!
问题是您调用 getopt
作为完整性检查,然后在成功时不使用其结果。这意味着第一个选项总是被丢弃。您可以通过将 -d
作为非第一选项来轻松验证这一点:
$ ./a.out -i in.dat -o out.dat -d
debug = 1
input file = (null), output file = out.dat
可以看到这次-d
确实生效了,但是第一个参数-i
没有设置。
有几种方法可以解决这个问题。推荐的方法(恕我直言)是删除第一个 getopt
调用。然后更改完整性检查以验证实际选项。也就是说,在 getopt
循环之后应该有代码验证是否已提供所有强制选项。
例如:
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;
}
因为您正在调用 getopt
两次,所以您需要在两次调用之间重置 optind = 1;
。