Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;在文件中存储对象_C++_Object_Binary_Storage_Fstream - Fatal编程技术网

C++ C++;在文件中存储对象

C++ C++;在文件中存储对象,c++,object,binary,storage,fstream,C++,Object,Binary,Storage,Fstream,我有一个对象列表,我想存储在一个尽可能小的文件中,以便以后检索。我一直在仔细阅读,并开始(我认为)理解,但有几个问题。以下是我正在处理的代码片段: static bool writeHistory(string fileName) { fstream historyFile; historyFile.open(fileName.c_str(), ios::binary); if (historyFile.good()) { list<

我有一个对象列表,我想存储在一个尽可能小的文件中,以便以后检索。我一直在仔细阅读,并开始(我认为)理解,但有几个问题。以下是我正在处理的代码片段:

    static bool writeHistory(string fileName)
{
    fstream historyFile;
    historyFile.open(fileName.c_str(), ios::binary);
    if (historyFile.good())
    {
        list<Referral>::iterator i;
        for(i = AllReferrals.begin(); 
                i != AllReferrals.end();
                i++)
        {
            historyFile.write((char*)&(*i),sizeof(Referral));
        }
        return true;
    } else return false;
}
摘自教程。现在我相信它正在做的是将对象转换为指针,获取值和大小并将其写入文件。但是如果它这样做了,为什么还要费心做转换呢?为什么不从头开始计算呢?为什么它需要这个尺寸?此外,据我当时的理解,为何

historyFile.write((char*)i,sizeof(Referral));
不编译?我是一个迭代器(迭代器不是指针吗?)。或者干脆

historyFile.write(i,sizeof(Referral));
我为什么要乱搞地址呢?我不是在文件中存储数据吗?如果地址/值是自己持久化的,为什么我不能将删除的地址存储在纯文本中,然后再获取它们的值呢

我还应该使用.txt扩展名吗那么我应该用什么来代替呢?我尝试了.dtb,但无法创建该文件实际上,我甚至无法使用ios::binary标志打开文件而不出错。我在传递文件名时也遇到了问题(作为字符串类字符串,由c_str()转换回来,它会编译,但会给出一个错误)


抱歉,有这么多小问题,但基本上都归结为如何有效地将对象存储在文件中?

Fstream.write只将原始数据写入文件。第一个参数是指向数据起始地址的指针。第二个参数是对象的长度(以字节为单位),因此write知道要写入多少字节

file.write((char*)&object,sizeof(className));
^ 此行将对象的地址转换为字符指针

historyFile.write((char*)i,sizeof(Referral));
^ 此行试图将对象(i)转换为字符指针(无效)

^ 此行正在传递write对象,但它需要一个char指针。

您尝试执行的操作(向文件中读取和写入原始内存)将调用未定义的行为,将中断任何非纯旧数据类型的操作,并且生成的文件将依赖于平台,编译器依赖,甚至可能依赖于编译器设置

historyFile.write((char*)i,sizeof(Referral));
C++没有任何内置的序列化复杂数据的方法。但是,您可能会发现有些库很有用。例如:

问题1为什么。。。不编译? 答:因为我不是推荐人*——它是一个列表::迭代器;;迭代器是指针的抽象,但它不是指针

问题#2我是否仍应使用.txt扩展名? 回答:可能不会。txt由许多系统与MIME类型text/plain关联

未问的问题:这有用吗?
回答:如果推荐信上有任何指针,。当您尝试从文件中读取引用时,指针将指向内存中某个曾经存在的位置,但不能保证那里有任何有效的内容,尤其是指针最初指向的内容。小心。

您尝试执行的操作称为序列化。Boost有这样做的理由

在某些情况下,在一些非常重要的条件下,您尝试做的事情可以起作用。它只适用于类型。它只保证对使用相同版本的编译器和相同参数编译的代码有效

(字符*)和(*i)

表示取迭代器i,解引用它以获取对象,取其地址并将其视为字符数组。这是写入文件的开始
sizeof(reference)
是将被写入的字节数


不,迭代器不一定是指针,尽管指针满足迭代器的所有要求

您已经看过了吗,它很健壮,有很好的文档,支持版本控制,如果您想切换到XML格式而不是二进制格式,那么会更容易

迭代器不是指针吗

迭代器的作用类似于外部的指针。在大多数(也许所有)情况下,它实际上是某种形式的对象,而不是一个简单的指针。迭代器可能包含一个指针作为内部成员变量,用于执行其工作,但如果需要,它也可能包含其他变量或附加变量

此外,即使迭代器内部有一个简单的指针,它也可能不会直接指向您感兴趣的对象。它可能指向容器类使用的某种簿记组件,然后可以使用该组件获取实际的感兴趣对象。幸运的是,我们不需要关心这些内部细节到底是什么

考虑到这一点,下面是在
(char*)&(*i)
中发生的事情

  • *i
    返回对列表中存储的对象的引用
  • &
    获取该对象的地址,从而生成指向该对象的指针
  • (char*)
    将该对象指针强制转换为char指针
这段代码是这样做的简短形式:

Referral& r = *i;
Referral* pr = &r;
char* pc = (char*)pr;

我为什么要胡闹 还有地址吗

为什么它需要这个尺寸

fstream::write
设计用于将一系列字节写入文件。它不知道这些字节意味着什么。给它一个地址,这样它就可以从地址指向的任何地方开始写入存在的字节。您给它一个大小,以便它知道要写入多少字节

file.write((char*)&object,sizeof(className));
因此,如果我这样做:

MyClass ExampleObject;
file.write((char*)ExampleObject, sizeof(ExampleObject));
然后它将直接存在于
ExampleObject
中的所有字节写入文件

注意:正如其他人所提到的,如果要编写的对象具有动态分配内存或以其他方式使用指针的成员,则