2017-10-05 96 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