find
并且substr
是两个非常好的函数重载系列,非常适合许多简单的解析问题,尤其是当您的语法检查只需要松散时。
要从版本向量中提取多个标量,请将找到的索引存储在某处:
const auto a = verstr.find('.');
const std::string major = verstr.substr(0, a);
然后用的重载之一重新使用它string::find
,说在之后开始搜索a
:
const auto b = verstr.find ('.', a+1);
const std::string minor = verstr.substr(a+1, b);
等等。
如果您需要语法检查,请将返回的索引与string::npos
:
const auto a = verstr.find('.');
if (std::string::npos == a)
.... bad syntax ....
此答案的 Pastebin 样式版本:
#include <string>
#include <stdexcept>
#include <iostream>
struct Version
{
std::string Major, Minor, Patch;
Version(std::string const &Major)
: Major(Major), Minor("0"), Patch("0")
{}
Version(std::string const &Major, std::string const &Minor)
: Major(Major), Minor(Minor), Patch("0")
{}
Version(std::string const &Major, std::string const &Minor, std::string const &Patch)
: Major(Major), Minor(Minor), Patch(Patch)
{}
};
std::ostream& operator<< (std::ostream &os, Version const &v)
{
return os << v.Major << '.' << v.Minor << '.' << v.Patch;
}
Version parse (std::string const &verstr) {
if (verstr.empty()) throw std::invalid_argument("bad syntax");
const auto first_dot = verstr.find('.');
if (first_dot == std::string::npos)
return Version(verstr);
const auto second_dot = verstr.find('.', first_dot+1);
if (second_dot == std::string::npos)
return Version(verstr.substr(0, first_dot),
verstr.substr(first_dot+1, second_dot));
return Version(verstr.substr(0, first_dot),
verstr.substr(first_dot+1, second_dot),
verstr.substr(second_dot+1));
}
进而
int main () {
std::cout << parse("1.0") << '\n'
<< parse("1.0.4+Patches(55,322)") << '\n'
<< parse("1") << '\n';
parse(""); // expected to throw
}