istream :: read和istream :: operator>>之间的区别

时间:2012-05-29 07:31:15

标签: c++

以下是我最初认为应该相同的两段代码:

{
    std::ifstream stream("test.bin", std::ios_base::in | std::ios_base::binary);
    unsigned char count = 128;
    unsigned char read = 0;
    unsigned char scanline[128];
    long long start = stream.tellg();
    while (count--) {
        stream >> scanline[read++]; // <---- This is the only line which differs
    }
    long long end = stream.tellg();
    std::cout << end - start << "\n";
}

{
    std::ifstream stream("test.bin", std::ios_base::in | std::ios_base::binary);
    unsigned char count = 128;
    unsigned char read = 0;
    unsigned char scanline[128];
    long long start = stream.tellg();
    while (count--) {
        stream.read((char*)&scanline[read++], 1); // <---- This is the only line which differs
    }
    long long end = stream.tellg();
    std::cout << end - start << "\n";
}

我的问题是第一个版本输出153(可能取决于输入数据)而第二个版本输出128(这是我的预期)。这必须与第一个版本中的数据提取方式有关,但我不明白为什么它不起作用。不应该只是打电话:

istream& operator>> (istream& is, unsigned char& ch);

每次移动文件一个字节?

2 个答案:

答案 0 :(得分:10)

如果您阅读operator>>的说明(例如here),那么您会看到它在阅读之前跳过空白,直到再次点击空白。空白不仅是空格(0x20),还包括标签(0x09)和换行符(0x0a)。

因此,如果您的二进制数据包含被视为文本文件空格的字节,则operator>>将读取但不存储它们,这将使tellg报告的数字出现偏差。

答案 1 :(得分:4)

在二进制文件中打开流时,使用operator>>不是一个好主意 我假设在你的情况下你的流中有某种白色空格字符(例如0x20) 您可以使用同时读取的skipws修饰符。