C++ - How to write and read a structure that contain an object ? (to write and read binary)

我们两清 提交于 2019-11-29 17:55:49

The file to read from was being opened as write only.

The actual std::string object can't be written that way. The actual object generally contains a couple of pointers and perhaps a size but not the actual character data. It need to be serialized.

If you're going to be writing C++ you should consider learning to use file streams rather than what you've got here.

#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <string>
#include <vector>

typedef struct s_test
{
    char cmd[5];
    std::string str;
}t_test;

void Write(int fd, struct s_test* test)
{
    write(fd, test->cmd, sizeof(test->cmd));
    unsigned int sz = test->str.size();
    write(fd, &sz, sizeof(sz));
    write(fd, test->str.c_str(), sz);
}

void Read(int fd, struct s_test* test)
{
    read(fd, test->cmd, sizeof(test->cmd));
    unsigned int sz;
    read(fd, &sz, sizeof(sz));
    std::vector<char> data(sz);
    read(fd, &data[0], sz);
    test->str.assign(data.begin(), data.end());
}

int main()
{
    t_test test;
    int fd = open("test", O_APPEND | O_CREAT | O_TRUNC | O_WRONLY, 0666);

    test.cmd[0] = 's';
    test.cmd[1] = 'm';
    test.cmd[2] = 's';
    test.cmd[3] = 'g';
    test.cmd[4] = 0;
    test.str = "hello world";
    std::cout << "Before Write: " << test.cmd << " " << test.str << std::endl;

    Write(fd, &test);
    close(fd);

    fd = open("test", O_RDONLY, 0666);
    t_test test2;
    Read(fd, &test2);
    std::cout << "After Read: " << test2.cmd << " " << test2.str << std::endl;
    close(fd);

    return (0);
}

See when you dump an structure into binary file its in memory image gets written on disk for example:

class X
{
public:
    int i;
    int j;
};

. . .

X lX;
lX.i= 10;
lX.j = 20;

an object of class lX when written into a binary file will look something like |10|20| i.e when you'll read it will work fine.

but for a class which contains any pointer like string does.

class Y
{
public:
    int* pi;
    int j;
};

. . .

Y lY;
lY.pi= new int(10); // lets assume this is created at memory location 1001
lY.j = 20;

so object lY will have value of pi as 1001 (not 10, as it is a pointer). now when you write lY to a binary file it will look like |10001|20| and when you'll read it back it will construct new object of Y (say lY2 )having values pi to be 1001 and j to be 20. Now we what do pi(which is a pointer) points to?? answer is garbage, that is something you are looking on screen. I guess you are using Windows to run this as Linux would have given you a segmentation fault.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!