2017-10-05 11 views
2

std :: string, std :: vector 또는 std :: array에 저장된 문자의 숫자를 구문 분석 할 수 있습니다. 그러나 문자가 std :: unique_ptr에있는 버퍼에있을 때 나는 그렇게 할 수 없습니다.boost :: spirit :: qi :: parse를 사용하여 문자 배열에서 double을 파싱하는 방법

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

참조 당사의 내가 정신을 강화하기 위해 다음 문자열로 버퍼를 복사 할 수 있지만이 사본 여기

을 피하려는 나의 시도 anwer

답변

1

boost::spirit::qi::parse은 시작과 끝 반복자를 사용합니다. 가능성이 높습니다 :

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

즉. 일반 포인터는 반복자로 작동하며 시작 포인터에 추가하여 끝 포인터를 형성 할 수 있습니다.

+0

이가이다 정답. 다음과 같이 수정하십시오. boost :: spirit :: qi :: parse (numeric2.get(), numeric2.get() + wcslen (numeric2.get()), num) 컴파일하지 않기 때문에 –

+0

일치해야하는 wcsnlen을 사용하도록 수정되었습니다. 와이드 char 형이며 버퍼의 끝에서 벗어나지 않도록 보장합니다. 예제 코드에서 어쨌든 입력 문자열의 길이를 단지 하드 코딩하는 것이 가장 좋습니다. –

0

너무 많은 일들이와 떨어져 있습니다

  • unique_ptr는
  • 는 당신이 자유롭게 불확정 값을 복사
  • qi::parse이 두 번째 매개 변수로 크기를 고려하지 않는 data() 멤버 함수가 없습니다 배열/unique_ptr<wchar_t[]>
  • 당신은 심지어 그것을 분석하려고합니다. 성령은 특별한으로 NUL 문자를 취급하지 않습니다, 그래서 당신은 구문 분석되지 않은 후행 쓰레기를 여기

지정되지 당신이 wcout 혼합하고

  • cout이있어 무시하는 경우에만 있기 때문에 당신이 올바르게 구문 분석하는 "것"이라고 대부분의 것들을 수정 :

    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가 돌볼 때 null 문자에 공백을 추가하는지 궁금합니다. –

    +0

    솔직히 말해서 나는 wcsncpy에 대한 문서를 본 적이 없다. (내 질문은 "wcsncpy"또는 "길이를 알고있는 경우 wcslen"을 사용하는 이유이다). – sehe