2017-10-05 56 views
2

我可以从存储在的std :: string,性病::向量或std ::字符数组解析数字。 但是,当字符在std :: unique_ptr中的缓冲区中时,我无法这样做。 我可以在缓冲区拷贝到一个字符串,则提振精神,但我想避免这种拷贝如何从使用boost ::精神::气字符数组解析双::解析

这里是我的尝试:

#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; 
} 

的修复:

boost::spirit::qi::parse(numeric2.get(), numeric2.get() + wcslen(numeric2.get()), num); 

见Zalman的前面回答

回答

1

boost::spirit::qi::parse需要开始和结束迭代器。您可能想要类似的东西:

boost::spirit::qi::parse(numeric2.get(), numeric2.get() + wcsnlen(numeric2.get(), max_size), num); 

也就是说,普通指针用作迭代器,并且可以通过添加到开始指针来形成结束指针。

+0

这是 正确答案。请修改如下,我会接受;升压::精神::齐::解析(numeric2.get(),numeric2.get()+ wcslen(numeric2.get()),NUM),因为它不会编译如 –

+0

固定使用wcsnlen,这应该匹配宽字符类型,并仍然保证不会跑出缓冲区的末尾。在示例代码中,无论如何,最好只是硬编码输入字符串的长度。 –

0

太多的东西了与此:

  • 的unique_ptr没有一个data()成员函数
  • qi::parse不采取大小作为第二个参数
  • 你慷慨复制不定值该阵列/ unique_ptr<wchar_t[]>
  • 更糟的是,你甚至试图解析它。精神不把NULL字符作为特殊,所以你“似乎”正确解析,只是因为你忽略未解析尾随垃圾
  • 你混合wcoutcout这是不确定的

这里有一个大多数事情的解决办法:

Live On Coliru

#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; 
    } 
} 
+0

添加演示[Live On Coliru](http://coliru.stacked-crooked.com/a/f35879c92c25580a)。 – sehe

+0

只是好奇为什么当wcsncpy会照顾到这个时为空字符添加空间。 –

+0

说实话,我从来没有看过的文档的'wcsncpy'(我的问题是“为什么要用'wcsncpy'或'wcslen'如果你已经知道长度”)。 – sehe