2

以下是我最初认为应该等效的两个代码片段:

{
    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);

并每次将filepos移动一个字节?

4

2 回答 2

10

如果您阅读operator>>(例如此处)的描述,那么您会看到它在阅读之前跳过了空白,直到它再次遇到空白。空白不仅是空格 ( 0x20),而且是制表符 ( 0x09) 和换行符 ( 0x0a) 之类的东西。

因此,如果您的二进制数据包含被视为文本文件空白的字节,operator>>则将读取但不存储它们,这将扭曲tellg.

于 2012-05-29T07:49:47.223 回答
4

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

于 2012-05-29T07:50:44.480 回答