I am using spiri::qi
to parse a text and pushing what I parse into a vector<string>
, for the most part its fine since they are mostly names and addresses, but there are also some numbers that I am parsing with double_
, but once I push it to the vector
it considers it a character code, like '\x3'
in lieu of 3.0
. I don’t want to make use of variant
since its too much work for just a few cases. Is there anyway I can convert the result of double_
to string
before pushing it?
Use raw[double_]
(or even more exactly as_string[raw[double_]]
).
The first works like any rule that has attribute compatibility with a container of characters. The latter atomically exposes a std::string
(there's one for std::wstring
as well).
BONUS
To complete Jonathan Mee's suggestion to "just use the language" (paraphrasing... :)) you can, see the last demo grammar below:
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
namespace qi = boost::spirit::qi;
namespace px = boost::phoenix;
int main() {
using It = std::string::const_iterator;
auto to_string_f = [](auto v) { return std::to_string(v); };
px::function<decltype(to_string_f)> to_string_ { to_string_f };
for (std::string const input : { "3.14", "+inf", "NaN", "-INF", "99e-3" })
{
for (auto const& grammar : std::vector<qi::rule<It, std::string()>> {
//qi::double_, // results in strange binary interpretations, indeed
qi::raw[ qi::double_ ],
qi::as_string [ qi::raw[ qi::double_ ] ],
qi::double_ [ qi::_val = to_string_(qi::_1) ],
})
{
auto f = input.begin(), l = input.end();
std::string result;
if (qi::parse(f, l, grammar, result))
std::cout << input << "\t->\t" << result << "\n";
else
std::cout << "FAILED for '" << input << "'\n";
}
}
}
Printing
3.14 -> 3.14
3.14 -> 3.14
3.14 -> 3.140000
+inf -> +inf
+inf -> +inf
+inf -> inf
NaN -> NaN
NaN -> NaN
NaN -> nan
-INF -> -INF
-INF -> -INF
-INF -> -inf
99e-3 -> 99e-3
99e-3 -> 99e-3
99e-3 -> 0.099000
Note that std::to_string
doesn't result in the literal input, so it might not roundtrip faithfully for your purposes.