2010-06-12 3 views
3

그래서 이진 파일을 구문 분석하고 일부 데이터를 추출하고 싶습니다. 내가 직면 한 문제는 char 스트림을 unsigned char 스트림으로 변환해야한다는 것입니다. 부스트 설명서를 읽기 , boost::iostreams::code_converter이에 대한 해결책이 될 것을 보인다, 그래서 나는이 시도 :boost :: iostreams를 사용하여 이진 파일을 바이트 단위로 파싱하십시오.

typedef unsigned char uint8_t; 
typedef boost::iostreams::stream<boost::iostreams::code_converter< 
    boost::iostreams::basic_array_source<uint8_t>, 
    std::codecvt<uint8_t, char, std::mbstate_t> > > array_stream; 

array_stream s; //initialized properly in the code 
unsigned char asd; 
s >> asd; 
std::cout << asd << std::endl; 

아이디어는 InternalType=uint8_tExternalType=charcodecvt을 지정했다. 불행히도 이것은 컴파일되지 않습니다. 질문은 다음과 같습니다. char 스트림을 uint8_t 스트림으로 변환하려면 어떻게해야합니까?

답변

2

아직이 문제가 발생했는지는 알 수 없지만, 그렇게한다면 달성하려는 목표를 정확히 설명 할 수 있습니까? 것은 내부적으로 char이고 unsigned char는 동일합니다. 그들은 단지 어딘가에 앉아있는 8 비트입니다. 변환이 필요 없습니다.

유일한 차이점은 사용시 컴파일러에서 해석하는 방법에 있습니다. 즉, 사용시 static_cast를 사용하여 대부분의 문제를 해결할 수 있어야합니다.

std :: cout는 char와 동일한 부호없는 char을 출력합니다. 당신이 수치를 원하는 경우에 당신은 두 번 캐스팅이 있습니다

array_stream s; //initialized properly in the code 
unsigned char asd; 
s >> asd; 

std:cout << int(asd); 

나는이에 불편을 볼 가능성이 높일 수 : IOSTREAMS 것은 :: 당신을 위해 할 수있는 몇 가지 방법을 가지고,하지만 난 부스트를 사용한 적이 iostreams 및 여기에 답변의 숫자를보고, 많은 사람들이 당신을 도울 수 없습니다. 다른 모든 방법이 실패하면 데이터를 다시 해석하십시오. 어쨌든 그것을 변환하는 것은 그것을 모두 복사하는 것을 의미한다면 나쁜 생각 일 것입니다.

+0

그래서 내가 원래 질문의 큰 그림은 내가 부스트 :: 정신을 부호의 스트림을주고 싶다고했다 추측 구문 분석 할 문자. 따라서 스트림에서 무언가를 읽으 려 할 때마다 코드 전체에 static_cast를 두는 것은 실행 가능하지 않습니다 (내 코드가 모든 읽기를 수행하지는 않습니다). 나는 결국 boost :: iostreams를 제거하고 정신에서 파생 된 반복기를 사용하여이 문제를 해결했다. – Zsol

1

uint8_t & 친구를 처리하는 맞춤식 기기를 작성할 수 있습니다. 다음은 예입니다

template <typename Container> 
class raw_back_insert_device 
{ 
public: 
    typedef char char_type; 
    typedef typename Container::value_type raw_char_type; 
    typedef boost::iostreams::sink_tag category; 

    raw_back_insert_device(Container& container) 
     : container_(container) 
    { 
    } 

    std::streamsize write(char const* s, std::streamsize n) 
    { 
     auto start = reinterpret_cast<raw_char_type const*>(s); 
     container_.insert(container_.end(), start, start + n); 
     return n; 
    } 

private: 
    Container& container_; 
}; 

template <typename Container> 
raw_back_insert_device<Container> raw_back_inserter(Container& cnt) 
{ 
    return raw_back_insert_device<Container>(cnt); 
} 

class raw_array_source : public boost::iostreams::array_source 
{ 
public: 
    template <typename Char> 
    raw_array_source(Char const* begin, Char const* end) 
     : boost::iostreams::array_source(
      reinterpret_cast<char const*>(begin), 
      reinterpret_cast<char const*>(end)) 
    { 
    } 

    template <typename Char> 
    raw_array_source(Char const* begin, size_t size) 
     : boost::iostreams::array_source(
      reinterpret_cast<char const*>(begin), 
      size) 
    { 
    } 

    template <typename Container> 
    raw_array_source(Container& container) 
     : raw_array_source(container.data(), container.size()) 
    { 
    } 

    std::streamsize read(char* s, std::streamsize n) 
    { 
     auto i = input_sequence(); 
     auto min = std::min(i.second - i.first, n); 
     std::copy(i.first, i.first + min, s); 
     return min; 
    } 
}; 

template <typename Container> 
raw_array_source raw_container_source(Container& container) 
{ 
    return raw_array_source(container); 
} 

당신의 다음과 같이 보일 것이다 수 :

typedef unsigned char uint8_t; 
typedef boost::iostreams::stream< 
    boost::iostreams::code_converter< 
     raw_array_source, 
     std::codecvt<uint8_t, char, std::mbstate_t> 
    > 
> array_stream; 

array_stream s; //initialized properly in the code 
unsigned char asd; 
s >> asd; 
std::cout << asd << std::endl;