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

后端 未结 2 1405
我寻月下人不归
我寻月下人不归 2020-12-22 12:53

I\'m trying to write a C structure in a file (to write in binary) and read it to recover it. I don\'t know if it is possible. Here is what I have :

head.hh:

相关标签:
2条回答
  • 2020-12-22 13:06

    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);
    }
    
    0 讨论(0)
  • 2020-12-22 13:16

    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.

    0 讨论(0)
提交回复
热议问题