std :: ifstream :: operator >> не может перевести 0xABCD в короткий текст? - PullRequest
0 голосов
/ 05 декабря 2011

Я пытаюсь прочитать двоичный файл, который представляет собой серию байтов и длин, закодированных в формате с прямым порядком байтов.
Я предполагал, что мог бы использовать для этого ifstream, открытый в режиме ios :: binary, но, по-видимому,Я не могу: когда я пытаюсь прочитать длинный, он устанавливает бит ошибки и выдает исключение.
Я не понимаю, почему он это делает.
Это мой код:

std::string fname = (
        boost::format(
            (
                boost::filesystem::initial_path()
                / "maps"
                / "w%02d.map"
            )
            .string() 
        )
        % mapNum
    )
    .str();
if (!boost::filesystem::exists(fname))
    throw std::runtime_error("No such map " + fname + "!");

std::ifstream file;
file.exceptions(std::ifstream::eofbit | std::ifstream::failbit | std::ifstream::badbit);
file.open(fname, std::ios::in | std::ios::binary);

char header[4];
file.read(header, 4);
if (!(header[0] == '!' && header[1] == 'I' && header[2] == 'D' && header[3] == '!'))
    throw std::runtime_error(fname + " is not a valida map file!");

unsigned short int RLEWtag = 0;
file >> RLEWtag;

и это первые 10 байт файла: 21 49 44 21 CD AB 40 00 40 00
Если это имеет значение, я запускаю это в VS2010 на 64-битной Windows 7.

1 Ответ

3 голосов
/ 05 декабря 2011

Вы используете форматированный ввод (т. Е. Оператор извлечения потока, operator>>), который ожидает текстовые данные;вместо этого вам нужно использовать форматированный ввод un , как вы это делали для чтения заголовка:

unsigned short RLEWtag;
char buf[2];
file.read(buf, 2);
std::memcpy(&RLEWtag, buf, 2);

Или, более кратко (спасибо @KerrekSB),

unsigned short RLEWtag;
file.read(reinterpret_cast<char*>(&RLEWtag), 2);
...