从c++二进制文件中读取结构

Reading a structure from a binary file in c++

本文关键字:读取 结构 二进制文件 c++      更新时间:2023-10-16

所以我试图从我写的二进制文件中读取结构,但有些东西似乎是错误的。下面是我的main:

//Fraction structure
struct Fraction
{
int num, den;
};

int main()
{
int menu_selection;
char slash;
fstream datafile; //creates file object
Fraction* f; //creates pointer for dam
//menu to the user
menu_selection = main_menu();
bool condition = true;
while (condition)
{
    switch(menu_selection)
    {
    case 1: //adds a new Fraction structure to binary file
        f = new Fraction; //dynamically allocating memory
        cout << "Enter fraction to add: "; //adds fraction to file
        cin >> f->num >> slash >> f->den;//stores input
        datafile.open("fractions.dat",ios:: out | ios:: app | ios::binary); //creates file
        datafile.write(reinterpret_cast<char *>(f),sizeof(Fraction));//stores fraction to file
        datafile.close();
        menu_selection = main_menu();
        break;
    case 2:
        menu_selection = main_menu();
        break;
    case 3: //displays the contents of the file to user
        datafile.open("fractions.dat", ios::in | ios::binary);
        while(!datafile.eof())
        {
            datafile.read(reinterpret_cast<char *>(f),sizeof(f));
            cout << f->num << "/" << f->den << " ";
        }
        datafile.close();
        menu_selection = main_menu();
        break;
    case 4:
        menu_selection = main_menu();
        break;
    case 5:
        menu_selection = main_menu();
        break;
    case 6: condition = false;
        return 0;
        break;
    default: cout << endl << "That is an invalid option. Please try again." << endl; //default option
        break;
    }
}
delete f;
}

当用户输入1时,我动态地为结构Fraction分配内存并将其写入二进制文件。我使用ios::app是因为我想在再次调用时添加到文件中。写或读功能有什么问题吗?当我按原样运行程序时,如果我输入一个分数,比如1/5,它显示1/5 5/5 5/5,但是如果我输入两个分数,比如1/5和2/6,它显示2/6 6/6 6/6。

    datafile.write(reinterpret_cast<char *>(f),sizeof(Fraction));//stores fraction to file

这没有任何意义。您必须将类实例转换为二进制格式来存储它。你不能告诉编译器假装你做了,而实际上你没有!

文件是字节流。为了在文件中存储内容,您必须为该内容指定一种格式,该格式以字节流(或块)的形式指定。您不能仅仅欺骗编译器以完全未指定或任意格式将一些内存块存储到磁盘上。它可能包含指针!

还有一个问题:

        datafile.read(reinterpret_cast<char *>(f),sizeof(f));

哎呀,f没有指向任何东西。因此,您现在已经告诉编译器将数据读取到没有特定位置。