【问题标题】:why fstream.read work and not >>? [duplicate]为什么 fstream.read 工作而不是 >>? [复制]
【发布时间】:2013-07-29 20:53:55
【问题描述】:

我想知道为什么我不能使用 std::ifstream>> 运算符从二进制文件中读取无符号整数。

#include <fstream>

    int main(int argc, char* argv[])
    {
        std::ifstream in(argv[1]);
        if(in.fail())
            return -1;

        unsigned int atom_size = 0;

        in.read(reinterpret_cast<char*>(&atom_size), 4);
        in >> atom_size;

        return 0;
    }

当我使用 in.read 时,我得到了我想要的值,但是当我使用 &gt;&gt; 运算符时,我的 atom_size 变量没有改变。为什么?

【问题讨论】:

    标签: c++ fstream


    【解决方案1】:

    显然您正在读取一个二进制文件。 read 命令将文件中请求的字节数复制到您提供的指针所指示的内存中。 &gt;&gt; 运算符希望找到要转换为整数的 ASCII 文本。这两个操作根本不一样。

    【讨论】:

    • 如果OP正在读取二进制文件,不应该以二进制模式打开流吗?
    • @DyP,可能是为了便携性和严格的正确性,是的。在许多系统上,这根本不重要。文本模式和二进制模式之间的区别通常与行尾处理等有关。在 OP 的简单程序中不太可能有区别。
    • 值得一提的是,标准区分了格式化输入函数operator&gt;&gt;(unsigned int&amp; val); 就是其中之一,而get, ignoreread未格式化的输入函数。自然,格式化输入函数没有格式化输入就无法工作。
    【解决方案2】:

    将二进制数据作为字符读取与将数据作为整数读取是有区别的。例如,数字 5 是 00000101。字符“5”是 00110101。

    &gt;&gt; 操作符正在读取 字符,所以当它看到 00110101 时,它会假定这是 5 的字符。如果您尝试读入 int,那么 &gt;&gt; 将正确地将其转换为 00000101 并将该值存储在 int 中。但是如果角色是例如像a 这样的字母,它不对应于一个有效的int,&gt;&gt; 将静默失败(它不会崩溃,但它会返回false)。

    在您的二进制文件中,例如,数字 5 可能存储为 00000101,但 &gt;&gt; 认为它应该将其读取为 字符(即 ENQ 字符)。这不能转换为 int,因此行 in &gt;&gt; atom_size; 将静默失败。实际上,它返回一个istream&amp;,可以转换为bool,因此您可以检查它是否失败:

    if(!(in >> atom_size)) {
      cout << "Failed to read into atom_size" << endl;
    }
    

    【讨论】:

    • 实际上,它返回一个对流的引用,它有一个显式转换为布尔值,因此您可以检查它是否失败。如果operator&gt;&gt; 返回了bool,那么你就不能说cin &gt;&gt; a &gt;&gt; b &gt;&gt; c
    • @BenVoigt 当然,感谢您指出这一点。稍微更改了我的描述以考虑到这一点
    • 格式化输入函数是格式化输入函数,无论流是二进制还是文本模式。它仍将使用语言环境的num_get 工具来读取和转换数字,对于大多数具有默认 C 语言环境的编译器来说,它将执行 ASCII 文本 -> int 转换。
    • @DyP 所以以二进制形式打开它不会有帮助吗?有没有办法解决这个问题,即仍然使用&gt;&gt; 阅读?
    • @maditya 我认为使用&gt;&gt; 从二进制文件/流中读取int 有一些丑陋的技巧,但它们比仅仅使用read 要丑陋得多。此外,使用read 会立即表明您正在处理二进制/未格式化数据。
    猜你喜欢
    • 1970-01-01
    • 2019-07-13
    • 2011-02-14
    • 2010-09-30
    • 1970-01-01
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 2013-07-01
    相关资源
    最近更新 更多