逐字节读取二进制 istream

新手上路,请多包涵

我试图使用 ifstream 逐字节读取二进制文件。我之前使用过像 get() 这样的 istream 方法来一次读取二进制文件的整个块而没有问题。但我目前的任务是逐字节进行,并依靠 io 系统中的缓冲来提高效率。问题是我似乎比我应该早几个字节到达文件末尾。所以我写了下面的测试程序:

 #include <iostream>
#include <fstream>

int main() {
    typedef unsigned char uint8;
    std::ifstream source("test.dat", std::ios_base::binary);
    while (source) {
        std::ios::pos_type before = source.tellg();
        uint8 x;
        source >> x;
        std::ios::pos_type after = source.tellg();
        std::cout << before << ' ' << static_cast<int>(x) << ' '
                  << after << std::endl;
    }
    return 0;
}

这会转储 test.dat 的内容,每行一个字节,显示文件之前和之后的位置。

果然,如果我的文件恰好有两个字节的序列 0x0D-0x0A(对应于回车和换行),这些字节就会被跳过。

  • 我已经以二进制模式打开了流。这不应该阻止它解释行分隔符吗?
  • 提取运算符是否总是使用文本模式?
  • 从二进制 istream 逐字节读取的正确方法是什么?

Windows 上的 MSVC++ 2008。

原文由 Adrian McCarthy 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1k
2 个回答

> 提取器用于格式化输入;他们跳过空格(默认情况下)。对于单字符无格式输入,您可以使用 istream::get() (返回一个 int ,如果读取失败,则为 EOF,或 [0,UCHAR_MAX] 范围内的值)或 istream::get(char&) (将读取的字符放入参数中,返回转换为 bool 的内容,如果读取成功则为 true,如果读取失败则为 false。

原文由 James Kanze 发布,翻译遵循 CC BY-SA 3.0 许可协议

正如其他人提到的,您应该使用 istream::read() 。但是,如果您必须使用格式化提取,请考虑 std::noskipws

原文由 Robᵩ 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题