Я читаю заголовок wav
файл и заполнение моих учеников с помощью <<
(влево) и |
(или) когда я читаю необработанные байты из файла. Теперь по совпадению у меня следующая ситуация
где uBytesPerSecond
имеет тип unsigned
а также data
имеет char*
так что я могу использовать std::fstream::read
,
Теперь, когда я следую за созданием uBytesPerSecond
в отладчике
this->uBytesPerSecond |= data[0x1F]; //0x00 ->uBytesPerSecond = 0x00000000
this->uBytesPerSecond <<= 8; // ->uBytesPerSecond = 0x00000000
this->uBytesPerSecond |= data[0x1E]; //0x02 ->uBytesPerSecond = 0x00000002
this->uBytesPerSecond <<= 8; // ->uBytesPerSecond = 0x00000200
this->uBytesPerSecond |= data[0x1D]; //0xb1 ->uBytesPerSecond = 0xffffffb1 !!!
this->uBytesPerSecond <<= 8; // ->uBytesPerSecond = 0xffffb100
this->uBytesPerSecond |= data[0x1C]; //0x10 ->uBytesPerSecond = 0xffffb110
Ожидаемый результат в этом случае uBytesPerSecond = 0x00002b110
, Пожалуйста, расскажите, что здесь происходит и как я могу это решить.
я использую MSVC2012
и Windows 8, это VC++-Console
-приложение.
Проблема в том, что для вашей платформы char
это подписанный тип. Следовательно, содержащееся значение будет расширено до 32 бит для операции или, давая вам 0xffffffb1
за data[0x1D]
,
Чтобы решить эту проблему, просто измените тип data
в unsigned char*
,
Редактировать: Как отмечено в комментариях, еще одним решением проблемы будет явная маскировка операнда с помощью 0xFF
: this->uBytesPerSecond |= data[0x1F] & 0xFF
и так далее.
Почему бы не использовать объединение вместо того, чтобы возиться с битами или сдвигами? Что-то вроде
union ByteWord
{
unsigned int word;
char bytes[sizeof(unsigned int)];
}
Тогда вы можете просто сделать
ByteWord data;
myStream.read(data.bytes, sizeof(unsigned int));
this->uBytesPerSecond = myStream.word;
использование ntohl(myStream.word)
если вам это нужно поменять местами.