C++ 如何使用boost::spirit::qi::parse从字符数组中解析double
我可以从存储在std::string、std::vector或std::array中的字符解析数字。 但是,当字符位于std::unique\u ptr中保存的缓冲区中时,我无法这样做。 我可以将缓冲区复制到一个字符串中,以增强精神,但我希望避免这种复制 以下是我的尝试:C++ 如何使用boost::spirit::qi::parse从字符数组中解析double,c++,c++11,boost-spirit,C++,C++11,Boost Spirit,我可以从存储在std::string、std::vector或std::array中的字符解析数字。 但是,当字符位于std::unique\u ptr中保存的缓冲区中时,我无法这样做。 我可以将缓冲区复制到一个字符串中,以增强精神,但我希望避免这种复制 以下是我的尝试: #include<memory> #include<array> #include<iostream> #include "boost/spirit/include/qi.hpp" in
#include<memory>
#include<array>
#include<iostream>
#include "boost/spirit/include/qi.hpp"
int main()
{
const int max_size = 40;
std::array<wchar_t, max_size> numeric1;
std::wstring src = L"5178120.3663";
std::wcsncpy(numeric1.data(), src.data(), max_size);
double num = 0.0;
boost::spirit::qi::parse(numeric1.begin(), numeric1.end(), num);
std::cout.precision(15);
std::cout << num << std::endl; // OK
std::unique_ptr<wchar_t[]> numeric2(new wchar_t[max_size]);
std::wcsncpy(numeric2.get(), src.data(), max_size);
std::wcout << L"ok = " << std::wstring(numeric2.get()) << std::endl; // OK
boost::spirit::qi::parse(numeric2.data(), max_size, num); // fails to compile
std::cout.precision(15);
std::cout << num << std::endl;
// 'boost::spirit::qi::parse': no matching overloaded function found
return 0;
}
请参阅Zalman的anwer
boost::spirit::qi::parse
使用开始和结束迭代器。您可能需要以下内容:
boost::spirit::qi::parse(numeric2.get(), numeric2.get() + wcsnlen(numeric2.get(), max_size), num);
也就是说,普通指针作为迭代器工作,您可以通过添加到开始指针来形成结束指针。这样做会导致太多问题:
- unique\u ptr没有
成员函数data()
不将大小作为第二个参数qi::parse
- 可以将不确定值自由复制到数组/
unique\u ptr
- 更糟糕的是,你甚至试图解析它。Spirit不会将NUL字符视为特殊字符,所以您“似乎”能够正确解析,只是因为您忽略了未解析的尾随垃圾
- 您正在混合
和wcout
,这是未指定的cout
#include <boost/spirit/include/qi.hpp>
#include <array>
#include <iostream>
#include <memory>
int main() {
const int max_size = 40;
std::wstring src = L"5178120.3663";
const int actual_len = src.length() + 1; // include NUL character
{
std::array<wchar_t, max_size> numeric1;
std::wcsncpy(numeric1.data(), src.data(), actual_len);
double num = 0.0;
boost::spirit::qi::parse(numeric1.begin(), numeric1.end(), num);
std::wcout.precision(15);
std::wcout << num << std::endl; // OK
}
{
std::unique_ptr<wchar_t[]> numeric2(new wchar_t[max_size]);
std::wcsncpy(numeric2.get(), src.data(), actual_len);
double num = 0.0;
boost::spirit::qi::parse(numeric2.get(), numeric2.get() + actual_len, num);
std::wcout.precision(15);
std::wcout << num << std::endl;
}
}
#包括
#包括
#包括
#包括
int main(){
const int max_size=40;
标准::wstring src=L“5178120.3663”;
const int actual_len=src.length()+1;//包含NUL字符
{
std::数组numeric1;
std::wcsncpy(numeric1.data(),src.data(),实际长度);
双数值=0.0;
boost::spirit::qi::parse(numeric1.begin(),numeric1.end(),num);
标准:输出精度(15);
std::wcout这是正确的答案。请修改如下,我将接受;boost::spirit::qi::parse(numeric2.get(),numeric2.get()+wcslen(numeric2.get()),num)因为它不会编译为固定使用wcsnlen,它应该匹配宽字符类型,并且仍然保证不会耗尽缓冲区的末尾。在示例代码中,可能最好只是硬编码输入字符串的长度。添加了演示。只是好奇为什么要为空字符添加空间,而wcsncpy会解决这个问题。说实话我从未看过wcsncpy
的文档(我的问题是“如果你已经知道长度,为什么要使用wcsncpy
或wcslen
)。
#include <boost/spirit/include/qi.hpp>
#include <array>
#include <iostream>
#include <memory>
int main() {
const int max_size = 40;
std::wstring src = L"5178120.3663";
const int actual_len = src.length() + 1; // include NUL character
{
std::array<wchar_t, max_size> numeric1;
std::wcsncpy(numeric1.data(), src.data(), actual_len);
double num = 0.0;
boost::spirit::qi::parse(numeric1.begin(), numeric1.end(), num);
std::wcout.precision(15);
std::wcout << num << std::endl; // OK
}
{
std::unique_ptr<wchar_t[]> numeric2(new wchar_t[max_size]);
std::wcsncpy(numeric2.get(), src.data(), actual_len);
double num = 0.0;
boost::spirit::qi::parse(numeric2.get(), numeric2.get() + actual_len, num);
std::wcout.precision(15);
std::wcout << num << std::endl;
}
}