Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/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++_Arrays_Class_Serialization_Byte - Fatal编程技术网

C++ 转换c++;类转换为字节数组

C++ 转换c++;类转换为字节数组,c++,arrays,class,serialization,byte,C++,Arrays,Class,Serialization,Byte,通过使用ios::binary编写以下学生类,可以将其转换为二进制文件 #include <fstream> #include <iostream> using namespace std; class Student{ public: char name[40], address[120], gender; double age; bool is_blabla; }; int main() { Stu

通过使用ios::binary编写以下学生类,可以将其转换为二进制文件

#include <fstream>
#include <iostream>
using namespace std;

class Student{
    public:
        char name[40], address[120], gender;
        double age;
        bool is_blabla;
};

int main() {

    Student one;
    strcpy(one.name, "Cancan Can");
    strcpy(one.address, "example example exampla");
    one.gender = 'M';
    one.age = 25;
    one.is_blabla = true;

    ofstream ofs("fifthgrade.ros", ios::binary);
    ofs.write((char *)&one, sizeof(one));

    Student two;
    ifstream ifs("fifthgrade.ros", ios::binary);
    ifs.read((char *)&two, sizeof(two));

    // check if the data is OK
    cout << "Student Name: " << two.name << endl;


    return 0;
}

只需使用
std::stringstream
而不是
std::ofstream


然后,使用
std::stringstream::str()
访问
char*
(此返回是一个
std::string
,您可以在其上使用
std::string::c_str()
检索
char*

所有对象都可以作为其组成部分
char
访问,只需获取一个指针并将其强制转换即可

尽管如此,即使您想将其写入二进制文件(与写入文本表示相反),也不要只写入其原始字节:

  • 对象可能包含许多非值位(如填充、未使用的缓冲区等)。这些可能包含以前记录的信息,您不应泄露这些信息
  • 对象可能包含指向其他数据的指针、句柄或其他引用。这些信息无法从按位复制中恢复,因为它们所指示的信息是重要的部分,不会存在

顺便说一句:
ios::binary
只会禁用文本文件的翻译。(单形体上的标识,窗口上的换行……)

如果需要一种更增强的方式,请考虑以下方式:

  • Boost.Serialization()
  • Google协议缓冲区()

  • 你能详细说明一下“无价值位”吗?你是什么意思?“所有对象都可以作为其组成字符访问,只需获取一个指针并将其强制转换即可。”这难道不具有危险的误导性吗?这是真的,但它忽略了语义上构成“对象”的内容。i、 e.您不能通过简单地将指针投射到“容器”来序列化
    std::string
    。@LightnessRacesinOrbit:我稍后解释为什么这并不总是足够好。“非值位”还可能包括派生类中的vTable项等内容。@icabod:实际的vTable肯定会产生值,因为它决定了实际的类型。因此,我宁愿把它放在隐藏的指针、句柄和其他有趣的地方。正如下面的答案中所说的,只需将数据复制到缓冲区(向量、字符串,它们都可以正常工作。请注意,如果你的类中没有复杂的类型,也就是说,如果你的类是POD(普通的旧数据),所有这些都可以正常工作如果您开始使用动态分配,事情会变得复杂,您需要提供自己的方法来序列化/反序列化对象。通常这是通过C++11中的implementig operators>来完成的。您有一个is_pod方法来检查您的结构是否是一个pod。由于端点和对齐,它已经很复杂了。也就是说,请注意您的假设关于这种序列化格式的可移植性(阅读:一点也不)@dau_sama,这个例子是一个虚构的例子。我实际上有复杂的类,它们有动态状态和方法。所以我明白你的意思。你能给我一个资源/网站,让我看看如何使用位运算符序列化复杂的类吗?@cancan如果你有复杂的类,这并不容易。你可以检查一下,是好还是坏d他将原始字节从他的学生对象复制到流中?关于
    ios::binary
    ,他还问了些什么?我不明白为什么生成的字符*不能写入ios:binary文件。
    class Student{
        public:
            char name[40], address[120], gender;
            double age;
            bool is_blabla;
    
            void set_values (int,int);
            int doubleage() {return age*2;}
    };