如何为仿wc命令实现命令行参数解析功能?
类wc命令的参数解析实现方案
需求回顾
我实现了一个类wc命令的程序,其中get_counts函数可以读取文本文件,返回包含行数、单词数、字符数的数组。现在需要实现命令行参数解析逻辑,满足以下规则:
- 无参数时,默认输出全部三个统计项
- 重复指定同一参数(如
-l -l)仅生效一次 - 参数后可跟随多个文件名(例如
./wc -l -c alice.txt anh.txt)
已有实现代码
#include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <stdbool.h> int *get_counts(char *filename) { FILE *file = fopen(filename, "r"); if (file == NULL) { printf("NULL FILE"); exit(1); } int c; bool whitespace = true; static int arr[3] = {0,0,0}; // 重置静态数组,避免残留上一次统计结果 arr[0] = 0; arr[1] = 0; arr[2] = 0; for(;;) { c = fgetc(file); if (c == EOF) { break; } else if (c == '\n') { arr[0]++; } else if (whitespace && !isspace(c)) { arr[1]++; whitespace = false; } else if (!whitespace && isspace(c)) { whitespace = true; } arr[2]++; } fclose(file); return arr; }
注:原代码的静态数组会残留上一次调用结果,这里添加了重置逻辑,确保每次统计针对当前文件。
参数解析的实现思路
用三个布尔变量标记是否输出对应统计项,遍历命令行参数时:
- 初始化
show_lines、show_words、show_chars为true(无参数默认全输出) - 遍历每个参数:
- 若参数是
-l/-w/-c,将对应标记位设为true,首次指定参数时关闭其他默认项,后续添加参数仅开启对应项 - 若非参数格式,判定为文件名,加入文件列表
- 若参数是
伪代码
初始化 show_lines = true, show_words = true, show_chars = true 初始化 has_specified = false, 文件列表 = 空数组 遍历 argv[1] 到 argv[argc-1]: 当前参数 = argv[i] 如果 当前参数 == "-l": show_lines = true 如果 has_specified 为 false: show_words = false; show_chars = false has_specified = true 否则如果 当前参数 == "-w": show_words = true 如果 has_specified 为 false: show_lines = false; show_chars = false has_specified = true 否则如果 当前参数 == "-c": show_chars = true 如果 has_specified 为 false: show_lines = false; show_words = false has_specified = true 否则: 将 当前参数 加入 文件列表 如果 has_specified 为 false: 重置 show_lines、show_words、show_chars 为 true(全输出) 遍历 文件列表 中的每个文件: counts = get_counts(文件名) 按标记位输出对应统计值,最后输出文件名
C语言具体实现代码
#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { bool show_lines = true; bool show_words = true; bool show_chars = true; bool has_specified = false; char *filenames[argc]; int file_count = 0; for (int i = 1; i < argc; i++) { if (strcmp(argv[i], "-l") == 0) { show_lines = true; if (!has_specified) { show_words = false; show_chars = false; } has_specified = true; } else if (strcmp(argv[i], "-w") == 0) { show_words = true; if (!has_specified) { show_lines = false; show_chars = false; } has_specified = true; } else if (strcmp(argv[i], "-c") == 0) { show_chars = true; if (!has_specified) { show_lines = false; show_words = false; } has_specified = true; } else { filenames[file_count++] = argv[i]; } } if (!has_specified) { show_lines = true; show_words = true; show_chars = true; } for (int i = 0; i < file_count; i++) { int *counts = get_counts(filenames[i]); if (show_lines) printf("%d ", counts[0]); if (show_words) printf("%d ", counts[1]); if (show_chars) printf("%d ", counts[2]); printf("%s\n", filenames[i]); } return 0; }
关键说明
has_specified标记是否有用户显式指定参数,实现多参数组合(如-l -c会同时输出行数和字符数)- 重复参数不会改变结果,因为标记位仅会被设为
true,重复设置无影响 - 所有非
-l/-w/-c的参数都会被视为文件名,支持多文件输入
内容的提问来源于stack exchange,提问作者Jason Fan
相关产品推荐
相关产品推荐

