如果程序被指定像这样运行,那么在c++中解析命令行参数的最佳方式是什么:
prog [-abc] [input [output]]
是否有某种方法可以在标准库中实现这一点,或者我需要自己编写代码?
相关:
在unicode c++应用程序中解析命令行参数
如果程序被指定像这样运行,那么在c++中解析命令行参数的最佳方式是什么:
prog [-abc] [input [output]]
是否有某种方法可以在标准库中实现这一点,或者我需要自己编写代码?
相关:
在unicode c++应用程序中解析命令行参数
当前回答
在c++中,答案通常在Boost中…
提振。程序选项
其他回答
还有一个谷歌库可用。
实际上,命令行解析已经“解决”了。随便选一个。
GNU C库中有这些工具,其中包括GetOpt。
如果你正在使用Qt并且喜欢GetOpt接口,那么froglogic已经在这里发布了一个不错的接口。
还有另一种选择是精益平均c++选项解析器:
http://optionparser.sourceforge.net
它是一个只包含头文件的库(实际上只有一个头文件),与所有其他建议不同 也是独立的,即它没有任何依赖关系。特别是,它不依赖于STL。它甚至不使用异常或任何其他需要库支持的东西。这意味着它可以与普通C语言或其他语言链接,而无需引入“外国”库。
像boost::program_options一样,它的API提供了方便的直接访问选项, 也就是说,你可以这样写代码
如果 (选项[帮助]) ... ;
and
int VERBOSE = options[VERBOSE].count();
然而,与boost::program_options不同的是,这只是使用一个带有(用户提供的)enum索引的数组。这提供了没有权重的关联容器的便利。
它有良好的文档记录,并具有公司友好的许可证(MIT)。
tlmc++ OP包含了一个很好的格式化程序,用于使用可以执行的消息 行换行和列对齐在本地化程序时非常有用,因为它可以确保即使在具有较长消息的语言中输出也会很好。它还省去了手动格式化80列的麻烦。
这是我最喜欢的执行命令行的方式,特别是,但绝对不是只有在效率是一个问题。这可能看起来有点过分,但我认为这种过分有一些缺点。
使用gperf进行高效的C/ c++命令行处理
缺点:
您必须首先运行一个单独的工具来生成C/ c++哈希表的代码 不支持特定的命令行接口。例如,posix简写系统“-xyz”用一个破折号声明多个选项是很难实现的。
优点:
Your command line options are stored separately from your C++ code (in a separate configuration file, which doesn't need to be read at runtime, only at compile time). All you have in your code is exactly one switch (switching on enum values) to figure out which option you have Efficiency is O(n) where n is the number of options on the command line and the number of possible options is irrelevant. The slowest part is possibly the implementation of the switch (sometimes compilers tend to implement them as if else blocks, reducing their efficiency, albeit this is unlikely if you choose contiguous values, see: this article on switch efficiency ) The memory allocated to store the keywords is precisely large enough for the keyword set and no larger. Also works in C
使用像eclipse这样的IDE,您可能可以自动化运行gperf的过程,因此您惟一需要做的就是在配置文件和switch语句中添加一个选项,然后按build…
我使用了一个批处理文件来运行gperf,并做了一些清理,并使用sed添加了包含保护(在gperf生成的.hpp文件上)…
所以,在你的软件中有非常简洁干净的代码和一个自动生成的哈希表文件,你真的不需要手动更改。我怀疑boost::program_options即使没有效率作为优先级,实际上也能打败它。
一个简单的解决方案是将argv放入std::map中,以便查找:
map<string, string> argvToMap(int argc, char * argv[])
{
map<string, string> args;
for(int i=1; i<argc; i++) {
if (argv[i][0] == '-') {
const string key = argv[i];
string value = "";
if (i+1 < argc && argv[i+1][0] != '-') {
value = string(argv[i+1]);
i++;
}
args[key] = value;
}
}
return args;
}
使用示例:
#include <map>
#include <string>
#include <iostream>
using namespace std;
map<string, string> argvToMap(int argc, char * argv[])
{
map<string, string> args;
for(int i=1; i<argc; i++) {
if (argv[i][0] == '-') {
const string key = argv[i];
string value = "";
if (i+1 < argc && argv[i+1][0] != '-') {
value = string(argv[i+1]);
i++;
}
args[key] = value;
}
}
return args;
}
void printUsage()
{
cout << "simple_args: A sample program for simple arg parsing\n"
"\n"
"Example usage:\n"
" ./simple_args --print-all --option 1 --flag 2\n";
}
int main(int argc, char * argv[])
{
auto args = argvToMap(argc, argv);
if (args.count("-h") || args.count("--help")) {
printUsage();
}
else if (args.count("--print-all")) {
for (auto const & pair: args)
cout << "{" << pair.first << ": " << pair.second << "}\n";
}
return 0;
}
输出:
$ ./simple_args --print-all --option 1 --flag "hello world"
{--flag: hello world}
{--option: 1}
{--print-all: }
这种方法肯定有很大的局限性,但我发现它很好地平衡了简单性和实用性。