2016-12-01 11 views
0

파일에 비트 필드 구조를 쓰고 읽는 중입니다. 예를 들어파일에서 /로 비트 필드 구조 쓰기/읽기

:

typedef struct{ 
    ushort 
       a:4, 
       b:4, 
       c:4, 
       d:4; 
} teststruct; 

내가 쓰고 내가 >>로 할 수있는

error: cannot bind bitfield 'a.teststruct::a' to 'quint16& {aka short unsigned int&}'

이것이

QDataStream &operator <<(QDataStream &st, const teststruct &a) 
{ 
    st <<a.a << a.b << a.c << a.d; 
    return st; 
} 

QDataStream &operator >>(QDataStream &st, teststruct &a) 
{ 
    st >>a.a >> a.b >> a.c >> a.d; 
    return st; 
} 

teststruct str1, str2; 
str1.a = 1; 
str1.b = 0; 
str1.c = 1; 
str1.d = 0; 

QFile f("testfile"); 
f.open(QFile::WriteOnly); 
QDataStream st(&f); 

st << str1; 
f.close(); 
f.open(QFile::ReadOnly); 
QDataStream st(&f); 
st >> str2; 
f.close(); 

처럼 읽을 수는 있지만 QDataStream::operator>>에서 나는 오류를 가지고 시도 연산자 또는 어쩌면 내 구조에 데이터를 읽는 다른 방법이 있습니까?

+0

당신은의 비트에 const가 아닌 참조를 가질 수 없습니다 들. 'QDataStream :: operator >> (quint16 & i)'는 매개 변수를 const가 아닌 참조로 사용합니다 (오류 메시지가 표시하는 것처럼). 그래서 오류가 발생합니다. – thuga

답변

0

예를 들어 파일에 저장된 데이터가 잘못되었을 수 있습니다. 당신은 당신이 기록 된 2 바이트를해야합니다 파일에 샘플 데이터 BitStruct bits{0x1, 0x2};를 쓸 때

QDataStream &operator <<(QDataStream &st, const BitStruct &a) 
{ 
    st <<a.b1 << a.b2; 
    return st; 
} 

:로 작성

struct BitStruct 
{ 
    uint8_t  b1:4; 
    uint8_t  b2:4; 
}; 

및 운영자 : 그래서 예를 들어, 다음과 같은 구조체를 가진. 파일의 이진 내용은 달성하고자하는 바가 아닌 0x01 0x02입니다.

이 때문에 b1 분야에서 st << a.b1 결과를 호출하는 것은,이 경우 대부분의 아마 quint8가 (당신이 docs에서 자세한 내용을보실 수 있습니다)이다 QDataStream에 의해 처리 유형 중 하나에 변환되는 사실에 발생합니다.

st.readRawData(reinterpret_cast<char*>(&a), sizeof(BitStruct)); 
: 당신이 QDataStream::operator>> 구현에 유사한 갱신을해야 같은 구조로 데이터를 읽을 한편

st.writeRawData(reinterpret_cast<const char*>(&a), sizeof(BitStruct)); 

:

이 문제를 해결하려면에 QDataStream::operator<< 구현을 수정할 수 있습니다

이렇게하면 구조를 원하는대로 간결하게 작성하고 이에 따라 특정 비트 필드를 읽을 수 있습니다.

이 방법을 사용하면 전체 구조를 단일 접근 방식으로 작성/읽기 할 수 있으므로 구조의 추가 성장 (추가 필드)에 대해 걱정할 필요가 없으며 두 연산자 구현을 모두 업데이트 할 필요가 없습니다.

0

비트 필드 구조가있는 이유는 크기가 ushort (실제로는 uint16_t)이며 그 값을 전달하는 것이 저렴하고 가능한 최소 공간이 필요하다고 가정합니다. 그건 좋은 이유 야. 그래서 같이 가자.

구조체의 메모리 내 레이아웃은 디스크상의 레이아웃과 아무 관계가 없습니다. 디스크상의 레이아웃은 QDataStream 및 그 연산자를 사용하는 방법에 따라 결정됩니다. 당신은 공간의 75 %를 낭비 쇼로 디스크 레이아웃 - 각각의 값은 16 비트 필요하지만, 단지 4 필요 :

(uint16_t a) (uint16_t b) (uint16_t c) (uint16_t d) 

키는 구조 사이의 인터페이스로서 중간 값을 사용하는 수정 데이터 스트림.

따라서 :

레이아웃이 지금 어떤 공간을 낭비하지 않으며, (사용 pseudotypes) 다음과 같습니다에 디스크
QDataStream &operator <<(QDataStream &st, const teststruct &a) 
{ 
    uint8_t v0 = (a.d << 4) | a.c; 
    uint8_t v1 = (a.b << 4) | a.a; 
    st << v0 << v1; 
    return st; 
} 

QDataStream &operator >>(QDataStream &st, teststruct &a) 
{ 
    uint8_t v0, v1; 
    st >> v0 >> v1; 
    a.a = v1; 
    a.b = v1>>4; 
    a.c = v0; 
    a.d = v0>>4; 
    return st; 
} 

:

[(uint4_t d) (uint4_t c)] [(uint4_t b) (uint4_t a)]