std::ifstream::operator>> 不能将0xABCD翻译成短文吗?

std::ifstream::operator>> cannot translate 0xABCD into a short?

本文关键字:gt 文吗 翻译 不能 ifstream operator std 0xABCD      更新时间:2023-10-16

我正在尝试读取一个二进制文件,该文件是一系列字节和长度以小端序格式编码的。
我曾假设我可以使用ios::binary模式打开的ifstream,但显然我不能:当我尝试读取long时,它会设置failbit并抛出异常。
我不明白它为什么这样做。
这是我的代码:

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
如果它很重要,我在64位Windows 7上的VS2010中运行它。

您正在使用格式化的输入(即流提取操作符,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);