简体   繁体   English

用C ++读/写文件

[英]Reading/Writing to a file in c++

I am trying to reading and write objects to a file in C++, writing the object works fine, reading gives segmentation core dump. 我试图在C ++中读取对象并将其写入文件,编写对象工作正常,读取给出分段核心转储。 I have commented the code for writing objects to file, while writing we can uncomment that part and comment the reading part. 我已经注释了将对象写入文件的代码,而编写时我们可以取消注释该部分并注释读取的部分。

#include<iostream>
#include<fstream>
#include<string>

using namespace std;

class RelianceMart{
    string name;
    double trolley_number;
public:
    RelianceMart(){
        name = "NA";
        trolley_number = 0;
    }
    RelianceMart(string name, double trolley_number){
        this->name = name;
        this->trolley_number = trolley_number;
    }
    void setname(string name){
        this->name = name;
    }
    string getname(){
        return name;
    }
    void settrolleynumber(double trolley_number){
        this->trolley_number = trolley_number;
    }
    double gettrolleynumber(){
        return trolley_number;
    }
};

int main(){
    string name;
    double trl_num; 
    RelianceMart mart[3];
    RelianceMart obj;
//  ofstream fout("PersistentStorage.txt");
/*
    for(int i=0;i<3;i++){
        cin>>name;
        cin>>trl_num;
        mart[i] = RelianceMart(name, trl_num);
        fout.write((char *) & mart[i], sizeof(mart[i])); 
    }

    fout.close();
*/
    ifstream fin("PersistentStorage.txt");

    while(!fin.eof()){
        fin.read((char *) & obj,sizeof(obj));
        cout<< obj.getname();
    }
    fin.close();

    return 0;
}

The members of std::string is really nothing more than a member variable for the length, and a member variable being a pointer to the actual string contents. std::string的成员实际上只是长度的成员变量,而成员变量是指向实际字符串内容的指针

Pointers are private and unique to a specific process in all modern protected multi-tasking operating systems, no other process (not even one started from the same program) can reuse the same pointer. 指针是私有的,并且对于所有受保护的现代多任务操作系统中的特定进程都是唯一的,其他任何进程(甚至不是从同一程序启动的进程)都无法重用同一指针。

When you write the RelianceMart objects, you write the pointer of the name string object to the file. 编写RelianceMart对象时,将name字符串对象的指针写入文件。 As mentioned above no other process can use this pointer, and therefore can't read the file. 如上所述,没有其他进程可以使用此指针,因此无法读取文件。

Furthermore when you attempt to read the raw objects, you read raw data overwriting the existing data in the constructed object, and the object won't be properly constructed anymore. 此外,当您尝试读取原始对象时,您读取的原始数据会覆盖已构造对象中的现有数据,并且该对象将无法再正确构造。

You also don't open the file in binary mode , which is wrong since you write and read raw binary data, not text. 您也不会以二进制模式打开文件,这是错误的,因为您写入和读取的是原始二进制数据,而不是文本。


The common solution is to use serialization , and the most common way to do it is simply to overload the "output" and "input" operators << and >> . 常见的解决方案是使用序列化 ,最常见的方法是简单地重载“ output”和“ input”运算符<<>>

In the overloaded functions you simply write and read each object as text, again using the formatted << and >> operators. 在重载函数中,您只需使用格式化的<<>>运算符,即可简单地以文本形式写入和读取每个对象。


Lastly, please read Why is iostream::eof inside a loop condition considered wrong? 最后,请阅读为什么循环条件中的iostream :: eof被认为是错误的?

I would use a serialization framework, you could use Google's Protocol Buffers( https://developers.google.com/protocol-buffers/ ). 我将使用序列化框架,可以使用Google的协议缓冲区( https://developers.google.com/protocol-buffers/ )。 If you consider a fullblown framework overkill, you can always write your own serialization framework, I've done that, I did use the JSON-format to encode the object. 如果您认为一个过时的框架过于强大,那么您始终可以编写自己的序列化框架,我做到了,我确实使用JSON格式对对象进行编码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM