Created
June 4, 2017 21:44
-
-
Save maddinat0r/99b64c46e0ec75848971d10f5790bc42 to your computer and use it in GitHub Desktop.
small cpp string parser based on boost::spirit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
#include <vector> | |
#include <boost/optional.hpp> | |
#include <boost/optional/optional_io.hpp> | |
#include <boost/spirit/include/qi.hpp> | |
namespace qi = boost::spirit::qi; | |
template<char Delimiter = ' ', typename... Args> | |
bool sscanfpp(std::string const &input, Args &...args) | |
{ | |
std::vector<std::string> params; | |
if (!qi::parse(input.begin(), input.end(), | |
+~qi::char_(Delimiter) % Delimiter, | |
params)) | |
{ | |
return false; | |
} | |
return sscanfpp_parse(params, std::forward<Args&>(args)...); | |
} | |
bool sscanfpp_parse(std::vector<std::string> ¶ms) | |
{ | |
return params.size() == 0; | |
} | |
// int overload | |
template<typename... Args> | |
bool sscanfpp_parse(std::vector<std::string> ¶ms, int &arg, Args& ...args) | |
{ | |
std::string const ¶m = params.front(); | |
bool res = qi::parse(param.begin(), param.end(), qi::int_, arg); | |
params.erase(params.begin()); | |
return res && sscanfpp_parse(params, std::forward<Args&>(args)...); | |
} | |
// float overload | |
template<typename... Args> | |
bool sscanfpp_parse(std::vector<std::string> ¶ms, float &arg, Args& ...args) | |
{ | |
std::string const ¶m = params.front(); | |
bool res = qi::parse(param.begin(), param.end(), qi::float_, arg); | |
params.erase(params.begin()); | |
return res && sscanfpp_parse(params, std::forward<Args&>(args)...); | |
} | |
// string overload | |
template<typename... Args> | |
bool sscanfpp_parse(std::vector<std::string> ¶ms, std::string &arg, Args& ...args) | |
{ | |
std::string const ¶m = params.front(); | |
//number as first char is not allowed to distinguish string from int/float | |
bool res = qi::parse(param.begin(), param.end(), qi::alpha >> *qi::char_, arg); | |
params.erase(params.begin()); | |
return sscanfpp_parse(params, std::forward<Args&>(args)...); | |
} | |
// optional int overload | |
template<typename... Args> | |
bool sscanfpp_parse(std::vector<std::string> ¶ms, boost::optional<int> &arg, Args& ...args) | |
{ | |
std::string const ¶m = params.front(); | |
bool res = qi::parse(param.begin(), param.end(), -qi::int_, arg); | |
if (arg) | |
params.erase(params.begin()); | |
return sscanfpp_parse(params, std::forward<Args&>(args)...); | |
} | |
// optional string overload | |
template<typename... Args> | |
bool sscanfpp_parse(std::vector<std::string> ¶ms, boost::optional<std::string> &arg, Args& ...args) | |
{ | |
std::string const ¶m = params.front(); | |
//number as first char is not allowed to distinguish string from int/float | |
bool res = qi::parse(param.begin(), param.end(), -(qi::alpha >> *qi::char_), arg); | |
if (arg) | |
params.erase(params.begin()); | |
return sscanfpp_parse(params, std::forward<Args&>(args)...); | |
} | |
int main() | |
{ | |
std::string const input{ "text 123 32.2421" }; | |
std::string text1; | |
boost::optional<std::string> text2; | |
int number = -1; | |
float flt = -1.f; | |
bool res = sscanfpp(input, text1, number, text2, flt); | |
std::cout << "result: " << res << std::endl; | |
std::cout << "text1: " << text1 << std::endl; | |
std::cout << "text2: " << text2 << std::endl; | |
std::cout << "number: " << number << std::endl; | |
std::cout << "float: " << flt << std::endl; | |
std::cin.get(); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment