如果程序被指定像这样运行,那么在c++中解析命令行参数的最佳方式是什么:
prog [-abc] [input [output]]
是否有某种方法可以在标准库中实现这一点,或者我需要自己编写代码?
相关:
在unicode c++应用程序中解析命令行参数
如果程序被指定像这样运行,那么在c++中解析命令行参数的最佳方式是什么:
prog [-abc] [input [output]]
是否有某种方法可以在标准库中实现这一点,或者我需要自己编写代码?
相关:
在unicode c++应用程序中解析命令行参数
当前回答
提振。Program_options
其他回答
如果你可以使用boost库,我推荐boost::program_options。
在STL和常规的c++ /C运行时库中都没有特定的东西。
我认为GNU GetOpt并不是马上就可以使用的。
Qt和Boost可能是一种解决方案,但您需要下载并编译大量代码。
所以我自己实现了一个解析器,它产生一个std::map<std::string, std::string>的参数。
例如,调用:
./myProgram -v -p 1234
地图将是:
["-v"][""]
["-p"]["1234"]
用法是:
int main(int argc, char *argv[]) {
MainOptions mo(argc, argv);
MainOptions::Option* opt = mo.getParamFromKey("-p");
const string type = opt ? (*opt).second : "";
cout << type << endl; /* Prints 1234 */
/* Your check code */
}
MainOptions.h
#ifndef MAINOPTIONS_H_
#define MAINOPTIONS_H_
#include <map>
#include <string>
class MainOptions {
public:
typedef std::pair<std::string, std::string> Option;
MainOptions(int argc, char *argv[]);
virtual ~MainOptions();
std::string getAppName() const;
bool hasKey(const std::string&) const;
Option* getParamFromKey(const std::string&) const;
void printOptions() const;
private:
typedef std::map<std::string, std::string> Options;
void parse();
const char* const *begin() const;
const char* const *end() const;
const char* const *last() const;
Options options_;
int argc_;
char** argv_;
std::string appName_;
};
MainOptions.cpp
#include "MainOptions.h"
#include <iostream>
using namespace std;
MainOptions::MainOptions(int argc, char* argv[]) :
argc_(argc),
argv_(argv) {
appName_ = argv_[0];
this->parse();
}
MainOptions::~MainOptions() {
}
std::string MainOptions::getAppName() const {
return appName_;
}
void MainOptions::parse() {
typedef pair<string, string> Option;
Option* option = new pair<string, string>();
for (const char* const * i = this->begin() + 1; i != this->end(); i++) {
const string p = *i;
if (option->first == "" && p[0] == '-') {
option->first = p;
if (i == this->last()) {
options_.insert(Option(option->first, option->second));
}
continue;
} else if (option->first != "" && p[0] == '-') {
option->second = "null"; /* or leave empty? */
options_.insert(Option(option->first, option->second));
option->first = p;
option->second = "";
if (i == this->last()) {
options_.insert(Option(option->first, option->second));
}
continue;
} else if (option->first != "") {
option->second = p;
options_.insert(Option(option->first, option->second));
option->first = "";
option->second = "";
continue;
}
}
}
void MainOptions::printOptions() const {
std::map<std::string, std::string>::const_iterator m = options_.begin();
int i = 0;
if (options_.empty()) {
cout << "No parameters\n";
}
for (; m != options_.end(); m++, ++i) {
cout << "Parameter [" << i << "] [" << (*m).first << " " << (*m).second
<< "]\n";
}
}
const char* const *MainOptions::begin() const {
return argv_;
}
const char* const *MainOptions::end() const {
return argv_ + argc_;
}
const char* const *MainOptions::last() const {
return argv_ + argc_ - 1;
}
bool MainOptions::hasKey(const std::string& key) const {
return options_.find(key) != options_.end();
}
MainOptions::Option* MainOptions::getParamFromKey(
const std::string& key) const {
const Options::const_iterator i = options_.find(key);
MainOptions::Option* o = 0;
if (i != options_.end()) {
o = new MainOptions::Option((*i).first, (*i).second);
}
return o;
}
一个简单的解决方案是将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: }
这种方法肯定有很大的局限性,但我发现它很好地平衡了简单性和实用性。
我喜欢C的getopt(),但是我老了。: -)
您可以为此使用已经创建的库
http://www.boost.org/doc/libs/1_44_0/doc/html/program_options.html