正在分析多个命令行开关
Parsing multiple command line switches
我正在开发一个程序,该程序将扫描目录中的文件信息。将有一些可选的开关,用户可以将其放入其中,以扫描某些文件组,或以某些方式扫描,或以特定方式输出。
例如,如果用户输入:filesum -rRc
,这将执行递归扫描,按升序输出文件,并且只扫描与C++相关的文件扩展名(.cpp|.h|.hpp等)。
我如何以最干净的方式做到这一点?我研究过getopt,但我根本不了解它的实现,很难用文档找到好的例子。
我曾想过将开关输入的命令行参数转换为字符串并进行解析,但这难道不需要多个if语句来查看参数中是否只有一个开关,或者是否可以执行以下操作,如-rc
吗?或者,我也在考虑根据输入的开关使用不同标志的while循环,但如果有更干净、更简单的方法,我将非常感谢任何建议。谢谢
如果可能的话,我宁愿不使用任何第三方库。
最干净的方法是使用Boost program_options
。
很有趣,我现在正在做这件事。我在这里只描述一下大概的想法。完整的代码目前超过500行,并使用更多的实用程序进行格式化等
作为一个例子,我正在制作程序help
(它是相当伪的)。一个普通结构包含程序所需的所有选项,以及默认值:
struct help_opt
{
string owner;
string path;
bool rec;
int depth;
help_opt() : owner(""), path("/"), rec(false), depth(0) { }
};
另一个结构为命令行参数建模:
struct help_args : public help_opt, public arguments <help_args>
{
template <typename S>
void define(S& s)
{
set(s, owner, "owner", 'w', "force <name> as owner", "name");
set(s, path, "output", 'o', "save all output to <path>", "path");
set(s, rec, "recurse", 'r', "recurse into sub-topics");
set(s, depth, "depth", 'd', "set <number> as maximum depth", "number");
}
string title() const { return "my help"; }
string usage() const { return "help [<options>] [<topic>]"; }
string info() const
{
return
"Display help on <topic>, "
"or list available topics if no <topic> is given.";
}
help_args(int argc, char* argv[]) : arguments(argc, argv) { }
};
其中类arguments
是我所需要的所有基础设施。所有参数以及元数据(名称、缩写等)都在define()
中定义,每个参数都通过调用方法set()
来定义。
参数s
用于支持多项操作,例如收集用户输入、构建帮助文本或显示用户给定的值。然后,我们将引用传递给每个成员,根据用户输入,这些成员可能会得到一个适当的值,或者保留默认值。然后是参数名称、缩写、完整帮助文本以及可选的参数名称。布尔参数被单独视为标志,不包含任何参数。
附加方法title()
、info()
等指定程序自定义的信息消息。
实际处理由arguments
的构造函数完成。这调用help_args
中的define()
,而CCD_13又调用arguments
中的CCD14。对于每个选项,都会扫描命令行输入,并根据需要更新变量。同时,收集元数据并自动为--help
、--usage
、--version
等选项生成输出,就像gnu程序中一样。
help_args
作为模板参数传递给arguments
的事实是允许从基类调用define()
,即使它是一个模板,因此不是虚拟的。如果只需要一个操作,那么我们可以切换回纯虚拟方法。
我希望这是干净的。我知道有很多可用的工具和库,但我真的更喜欢这种方式。我可以在准备好的时候分享实现,它几乎完成了。
我检查了gnucat如何处理命令行选项。我在C中写了一个例子。你可以传递标志,比如:cli-ab file或cli-b-ac file或cli-bc file-a
#include <stdio.h>
int main (int argc, char *argv) {
int c;
while ((c = getopt(argc, argv, "abc")) != -1) {
switch (c) {
case 'a':
printf("selected: an");
break;
case 'b':
printf("selected: bn");
break;
case 'c':
printf("selected: cn");
break;
default:
printf("Usage: cli -a/-b/-cn");
break;
}
}
}
- 从命令行c++发送文本文件名
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 数组长度,为什么从命令行获取时不能使用它?
- 如何处理linux终端中带有负号(-)的C++中的命令行参数
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 未定义的引用 .. 使用 OpenCV 编译 C++ 代码时,从命令行
- 通过 Openssl 命令行加密,通过 c++ 解密
- CMake "--target install"无需"--build"命令行
- 更改命令行 qt5 源代码构建配置的正确/快速方法
- 使用 C++ 将命令行参数拆分为参数/向量
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- LLVM | codegen 用于带有命令行选项的程序输入功能
- 如何在OMNET++中添加专门的命令行参数?
- Makefile g++ 使用命令行中的 -D 变量进行编译,默认值
- 如何禁用没有命令行开关的 gcc 警告?
- 如何使用 boost::p rogram_options 解析本身包含开关的命令行参数
- 正在分析多个命令行开关
- C++开关语句,使用命令行参数
- 我可以设置visual studio 2005命令行开关在我的代码(即通过pragma/define)