OpenCV CommandLineParser未指定参数
OpenCV CommandLineParser Unspecified Params
使用cv::CommandLineParser
时,是否可以解析任意长的非标志参数列表?
例如:
> app -a -b=2 a.txt b.txt c.txt ...
我想访问所有非标志"位置"参数,而不必在keys
规范中定义预定义的数量。此号码仅由应用程序的调用者决定。
OpenCV CommandLineParser
不能处理数目可变的位置参数。您可以:
- 传递一个额外的参数(例如
-N
),指定位置参数的数量; - 考虑所有不以
-
开头的参数都是位置参数。
然后,您可以使用与cv::CommandLineParser
相同的接口创建一个自定义命令行解析器,该解析器能够处理可变数量的位置参数。
选项1
struct CustomCLP
{
CustomCLP(int argc, const char* const argv[], const cv::String& keys, const String& positional_id)
{
String pos_key = "{" + positional_id + "|0|}";
cv::CommandLineParser pos_clp(argc, argv, pos_key);
_N = pos_clp.get<int>(positional_id);
cv::String pos_keys = keys;
for (int i=0; i<_N; ++i)
{
pos_keys += "{@pos" + to_string(i) + "||}";
}
_clp = new CommandLineParser(argc, argv, pos_keys);
}
~CustomCLP()
{
delete _clp;
}
bool check() const {return _clp->check();}
bool has(const cv::String& name) const {return _clp->has(name);}
template<typename T>
T get(const String& name, bool space_delete = true) const
{
return _clp->get<T>(name, space_delete);
}
template<typename T>
T get(int index, bool space_delete = true) const
{
return _clp->get<T>(index, space_delete);
}
int n_positional_args() const { return _N;}
private:
CommandLineParser* _clp;
int _N;
};
你可以指定额外的参数(例如-N
)来指定位置参数的数量。在构造函数中,解析这个数字,并为每个位置参数创建一个键。然后你可以像往常一样使用它。
选项2
// SO: http://stackoverflow.com/a/17976541/5008845
inline std::string trim(const std::string &s)
{
auto wsfront = std::find_if_not(s.begin(), s.end(), std::isspace);
return std::string(wsfront, std::find_if_not(s.rbegin(), std::string::const_reverse_iterator(wsfront), std::isspace).base());
}
struct CustomCLP2
{
CommandLineParser _clp;
vector<std::string> pos_args;
public:
CustomCLP2(int argc, const char* const argv[], const cv::String& keys) :
_clp(argc, argv, keys)
{
for (int i = 1; i < argc; ++i)
{
std::string s(argv[i]);
s = trim(s);
if (s[0] == '-') continue;
pos_args.push_back(s);
}
}
bool check() const { return _clp.check(); }
bool has(const cv::String& name) const { return _clp.has(name); }
template<typename T>
T get(const String& name, bool space_delete = true) const
{
return _clp.get<T>(name, space_delete);
}
template<typename T>
T get(int index, bool space_delete = true) const
{
stringstream ss;
ss << pos_args[index];
T t;
ss >> t;
return t;
}
template<>
cv::String get(int index, bool space_delete) const
{
return cv::String(pos_args[index]);
}
int n_positional_args() const { return pos_args.size(); }
};
在构造函数中,保存所有不以-
开头的参数。然后您可以像往常一样检索它。
注意接口与CommandLineParser是一致的(在这个例子中,about
、getPathToApplication
等几个方法是不可用的,但是很容易将它们添加到自定义类中)。
命令行参数为:
Option 1: -a -b=2 -N=3 a.txt b.txt c.txt
Option 2: -a -b=2 a.txt b.txt c.txt
代码:#include <opencv2opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
struct CustomCLP
{
CustomCLP(int argc, const char* const argv[], const cv::String& keys, const String& positional_id)
{
String pos_key = "{" + positional_id + "|0|}";
cv::CommandLineParser pos_clp(argc, argv, pos_key);
_N = pos_clp.get<int>(positional_id);
cv::String pos_keys = keys;
for (int i=0; i<_N; ++i)
{
pos_keys += "{@pos" + to_string(i) + "||}";
}
_clp = new CommandLineParser(argc, argv, pos_keys);
}
~CustomCLP()
{
delete _clp;
}
bool check() const {return _clp->check();}
bool has(const cv::String& name) const {return _clp->has(name);}
template<typename T>
T get(const String& name, bool space_delete = true) const
{
return _clp->get<T>(name, space_delete);
}
template<typename T>
T get(int index, bool space_delete = true) const
{
return _clp->get<T>(index, space_delete);
}
int n_positional_args() const { return _N;}
private:
CommandLineParser* _clp;
int _N;
};
// SO: http://stackoverflow.com/a/17976541/5008845
inline std::string trim(const std::string &s)
{
auto wsfront = std::find_if_not(s.begin(), s.end(), std::isspace);
return std::string(wsfront, std::find_if_not(s.rbegin(), std::string::const_reverse_iterator(wsfront), std::isspace).base());
}
struct CustomCLP2
{
CommandLineParser _clp;
vector<std::string> pos_args;
public:
CustomCLP2(int argc, const char* const argv[], const cv::String& keys) :
_clp(argc, argv, keys)
{
for (int i = 1; i < argc; ++i)
{
std::string s(argv[i]);
s = trim(s);
if (s[0] == '-') continue;
pos_args.push_back(s);
}
}
bool check() const { return _clp.check(); }
bool has(const cv::String& name) const { return _clp.has(name); }
template<typename T>
T get(const String& name, bool space_delete = true) const
{
return _clp.get<T>(name, space_delete);
}
template<typename T>
T get(int index, bool space_delete = true) const
{
stringstream ss;
ss << pos_args[index];
T t;
ss >> t;
return t;
}
template<>
cv::String get(int index, bool space_delete) const
{
return cv::String(pos_args[index]);
}
int n_positional_args() const { return pos_args.size(); }
};
int main(int argc, char* argv[])
{
String keys =
"{a | | whatever a}"
"{b | 1 | whatever b}";
//CustomCLP clp(argc, argv, keys, "N");
CustomCLP2 clp(argc, argv, keys);
if (clp.has("a")) {
cout << "Has <a>" << endl;
}
else {
cout << "Doesn't have <a>";
}
int b = clp.get<int>("b");
cout << "<b> : " << b << endl;
int N = clp.n_positional_args();
for (int i = 0; i < N; ++i)
{
cout << to_string(i) << ": " << clp.get<cv::String>(i) << endl;
}
return 0;
}
相关文章:
- 从 XML 中读取未指定结构的每个数据成员
- 为什么当函数参数未定义为常量引用时存在无限递归?
- 将对象传递给函数而不将其包装到 std::ref 中,而参数被指定为 const 引用
- 执行参数未提供预期结果
- 用数据填充未指定大小的数组
- 访问从联合与另一个成员集复制的联合中的一个成员是否未定义或未指定?
- 双循环变量的相等条件:未指定还是未定义
- SQL Server-未找到数据源名称,也未指定默认驱动程序
- 函数参数中数组大小未指定
- 只有未指定数量的参数的函数的目的是什么?
- 为什么在 c++ 中未指定函数参数的计算顺序
- 未指定模板参数,但仍有效
- 传递 C++11 中具有未指定参数的函数
- 当基类未指定构造函数时,如何使用仅具有带参数的构造函数的类派生基类?
- 将参数定义为未指定的模板类型
- 未指定的函数参数
- OpenCV CommandLineParser未指定参数
- 使用 range-for 循环:函数调用的参数太少,未指定单个参数'a'
- 如何在GMOCK中使用未指定的参数创建返回值
- 未指定的模板参数