问我如何打开命令行中提到的文件,并解析选项标志?
答这是一个实现了传统 Unix 风格的骨架argv解析,处理以-开头的选项标志,以及可选的文件名。(此示例接受的两个标志是-a和-b; -b接受一个参数。)
#include <stdio.h> #include <string.h> #include <errno.h> main(int argc, char *argv[]) { int argi; int aflag = 0; char *bval = NULL; for(argi = 1; argi < argc && argv[argi][0] == '-'; argi++) { char *p; for(p = &argv[argi][1]; *p != '\0'; p++) { switch(*p) { case 'a': aflag = 1; printf("-a seen\n"); break; case 'b': bval = argv[++argi]; printf("-b seen (\"%s\")\n", bval); break; default: fprintf(stderr, "unknown option -%c\n", *p); } } } if(argi >= argc) { /* no filename arguments; process stdin */ printf("processing standard input\n"); } else { /* process filename arguments */ for(; argi < argc; argi++) { FILE *ifp = fopen(argv[argi], "r"); if(ifp == NULL) { fprintf(stderr, "can't open %s: %s\n", argv[argi], strerror(errno)); continue; } printf("processing %s\n", argv[argi]); fclose(ifp); } } return 0; }(此代码假定fopen在失败时会设置errno,这并非绝对保证,但通常有效,并且能使错误消息更有用。另请参阅问题 20.4。)
有几种现成的函数可用于以标准方式进行命令行解析;最流行的函数是getopt(另请参阅问题 18.16)。以上示例已重写为使用getopt:
extern char *optarg; extern int optind; main(int argc, char *argv[]) { int aflag = 0; char *bval = NULL; int c; while((c = getopt(argc, argv, "ab:")) != -1) switch(c) { case 'a': aflag = 1; printf("-a seen\n"); break; case 'b': bval = optarg; printf("-b seen (\"%s\")\n", bval); break; } if(optind >= argc) { /* no filename arguments; process stdin */ printf("processing standard input\n"); } else { /* process filename arguments */ for(; optind < argc; optind++) { FILE *ifp = fopen(argv[optind], "r"); if(ifp == NULL) { fprintf(stderr, "can't open %s: %s\n", argv[optind], strerror(errno)); continue; } printf("processing %s\n", argv[optind]); fclose(ifp); } } return 0; }
上述示例忽略了一些细微之处:单个“-”通常被解释为“读取标准输入”;标记“--”通常表示选项的结束(正确实现的getopt会处理这种情况);当命令因参数不正确或缺失而调用时,打印用法消息是传统做法。
如果您想知道argv在内存中的布局,它实际上是一个“不规则数组”;请参阅问题 20.2 中的图片。另请参阅问题 8.2、13.7 和 19.20。
参考资料:K&R1 第 5.11 节 pp. 110-114
K&R2 第 5.10 节 pp. 114-118
ISO 第 5.1.2.2.1 节
H&S 第 20.1 节 p. 416
PCS 第 5.6 节 pp. 81-2,第 11 节 p. 159,pp. 339-40 附录 F
Schumacher 编,《C 语言软件解决方案》第 4 节 pp. 75-85