如何让getopt接收的多个命令行参数可单独使用也可组合生效
实现思路
你的原有代码的核心问题是:在getopt解析每一个参数的阶段就直接执行了目录遍历,导致每次只能触发单个规则,无法实现联动。正确的实现逻辑分为三步:
- 第一步:提前声明变量存储所有参数的配置状态,不要在解析参数时执行业务逻辑
- 第二步:在getopt循环中仅做参数解析、给配置变量赋值
- 第三步:所有参数解析完成后,统一执行一次目录遍历,遍历过程中组合判断所有已开启的规则
可直接参考的代码修改
首先定义全局的配置变量(也可封装为结构体传入printDIR,新手用全局变量更易实现):
#include <string.h> #include <stdlib.h> // 参数配置默认值代表对应参数未开启 static int enable_print_size = 0; // 对应-S:是否打印文件大小 static long min_size = -1; // 对应-s:最小文件大小阈值,<0表示未启用 static const char *name_filter = NULL; // 对应-f:文件名匹配子串,NULL表示未启用
修改getopt参数解析逻辑,不要在解析阶段调用printDIR:
while((c = getopt(argc, argv, "Ss:f:")) != -1){ switch(c){ case 'S': enable_print_size = 1; break; case 's': min_size = atol(optarg); // 可自行添加合法性判断:如果min_size<0就提示参数错误退出 break; case 'f': name_filter = optarg; break; default: fprintf(stderr, "用法: %s [-S] [-s 最小大小] [-f 匹配子串] [目录路径]\n", argv[0]); exit(EXIT_FAILURE); } } // 所有参数解析完成后,统一执行目录遍历 printDIR(cwd);
修改printDIR内部的文件处理逻辑,每个文件遍历后先做组合规则判断:
// 以下是printDIR遍历到单个文件时的处理逻辑伪代码 void handle_single_file(const char *file_path, const char *file_name, long file_size) { int is_match = 1; // 校验大小规则:如果开启了-s就判断 if (min_size >= 0 && file_size < min_size) { is_match = 0; } // 校验文件名规则:如果开启了-f就判断 if (is_match && name_filter != NULL && strstr(file_name, name_filter) == NULL) { is_match = 0; } // 所有规则匹配才输出 if (is_match) { if (enable_print_size) { printf("%s %ld\n", file_path, file_size); } else { printf("%s\n", file_path); } } }
效果验证
该实现天然支持参数任意组合、任意顺序、缺省不生效:
- 执行
./search -S -s 1024 -f tar:仅输出名称含tar、大小≥1024的文件,同时打印大小 - 执行
./search -s 2048:仅输出大小≥2048的文件名,不打印大小 - 执行
./search -f log -S:输出所有名称含log的文件,同时打印大小
内容的提问来源于stack exchange,提问作者Jimbo
相关产品推荐
相关产品推荐

