【问题标题】:`fout.write( reinterpret_cast<const char*>(&e), sizeof(e) );` why here casting into `const char*`?`fout.write(reinterpret_cast<const char*>(&e), sizeof(e));` 为什么这里要转换成`const char*`?
【发布时间】:2021-10-31 17:30:40
【问题描述】:

代码

#include <iostream>
#include <fstream>

struct emp
        {
            char name[20];
            int age;
        };

int main()
{
    emp e1={"Abhishek", 22},e2;
    
    std::ofstream fout;
    fout.open("vicky.dat", std::ios::out | std::ios::binary);
    fout.write(reinterpret_cast<const char*>(&e1),24);
    fout.close();

    std::ifstream fin;
    fin.open("vicky.dat", std::ios::in | std::ios::binary);
    fin.read(reinterpret_cast<char*>(&e2),24);
    fin.close();

    std::cout<<e2.name<<" "<<e2.age<<"\n";

    return 0;
}

为什么必须用writeread函数的第一个参数来做reinterpret_cast

为什么我们在writeread函数中分别将emp类型的地址转换为const char*char*

【问题讨论】:

  • 因为这是函数所需要的。
  • 因为write/read 分别以const char*/char* 作为参数,而你告诉编译器“我知道emp* 不是char*,但我希望你对待就像char*,我不在乎后果”。
  • @Yksisarvinen 知道了。
  • char 在 C++ 中是用词不当。更好的名称是byte:这两个函数(就像所有低级 IO 函数一样)在 字节缓冲区 上运行。
  • @RichardCritten 都不是字节(字节≠八位字节!)。在 C 和 C++ 中,char = 字节,根据定义。在大小和(别名和寻址)行为方面。

标签: c++ binaryfiles file-handling reinterpret-cast write


【解决方案1】:

为什么必须用writeread函数的第一个参数来做reinterpret_cast

因为write() 的第一个参数是const char*,而read() 的第一个参数是char*

为什么我们将emp 类型的地址分别转换为writewriteread 函数中的const char*char*

在您的情况下,您可以将两者都转换为 char* - 但是,在 write 的情况下,它不需要可变对象,因为它不会以任何方式修改它,您将无法write 一个 const 对象,如果您尝试转换为 char*

作品:

const emp e1 = {"Abhishek", 22};
fout.write(reinterpret_cast<const char*>(&e1), sizeof e1);

emp e2 = {"Foo", 23};
fout.write(reinterpret_cast<char*>(&e2), sizeof e2);
fout.write(reinterpret_cast<const char*>(&e2), sizeof e2);

甚至不编译:

const emp e1 = {"Abhishek", 22};
fout.write(reinterpret_cast<char*>(&e1), sizeof e1);

与问题无关但值得注意: 您已将emp 的大小硬编码为24。别。使用sizeof 获取实际大小。即使 int 在您当前的平台上是 4 字节,如果您在不同的平台上编译它也可能不是。

与上述相关:如果您希望文件格式在不同平台上工作并注意endianness,请使用固定宽度类型(如uint32_t 用于4 字节无符号整数) - 但仍使用sizeof,因为在添加/删除成员时手动计算大小容易导致错误。

【讨论】:

  • fout.write(reinterpret_cast&lt;char*&gt;(&amp;e2), sizeof e2); 它是如何工作的?
  • @AbhishekMane A char* 可以隐式转换为const char*(从非constconst 被认为是安全的)并且sizeof e2 给出e2 的大小字节。
  • 知道了。还有一件事sizeof e2 应该是sizeof(e2) 不是吗?
  • @AbhishekMane 太棒了! ...不,sizeof operator 有两种形式。 sizeof(type)sizeof expression。好吧,sizeof (expression) 也可以,但它仍会使用表达式形式。
  • 现在明白了。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-16
  • 1970-01-01
  • 1970-01-01
  • 2010-09-09
  • 1970-01-01
相关资源
最近更新 更多