【问题标题】:How to create a valid write to a binary file [closed]如何创建对二进制文件的有效写入[关闭]
【发布时间】:2020-11-17 08:19:54
【问题描述】:

我创建了要存储在二进制文件中的学生数据,但该文件已完全损坏。

我做错了什么?

记事本中存储的文本文件没有问题。

现在启动程序后进入后,只写这样的:

& Ô LC_CTYPE = C; LC_M0 & Ô RIC = C; LC_TIME = C

有人可以帮我解决这个问题吗?祝你有美好的一天:)

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <cstdlib>
    
    
    
    using namespace std;
    
    
    
    struct Student{
        string imie;
        string nazwisko;
        int nrAlbumu;
        int wiek;
        float srOcen;
    } dane;
    
    
    
    
    int main(){
    
    
    
    Student dane;
    
    cout << "Podaj imie:" << endl;
    cin >> dane.imie;
    cout << "Podaj nazwisko:" << endl;
    cin >> dane.nazwisko;
    cout << "Podaj nrAlbumu:" << endl;
    cin >> dane.nrAlbumu;
    cout << "Podaj wiek:" << endl;
    cin >> dane.wiek;
    cout << "Podaj srednia ocen:" << endl;
    cin >> dane.srOcen;
    
    
    cout << "Student " << dane.imie  <<" "<< dane.nazwisko << " o numerze albumu: " << dane.nrAlbumu << " ma lat " << dane.wiek << " ma srednia ocen rowna: " << dane.srOcen << endl;
    
    
//-------writing to the file starts here-------------------------

    ofstream ofs("dane.bin", ios::binary);
    
    Student* student = new Student;
    
    student->imie;
    student->nazwisko;
    student->nrAlbumu;
    student->wiek;
    student->srOcen;
    
    ofs.write((char*)(student), sizeof(Student));
    ofs.close();
    
     delete student;
    
 //-------------reading starts here ---------------------------
    
    ifstream ifs("dane.bin", ios::binary);
    
    char* temp = new char[sizeof(Student)];
    ifs.read(temp, sizeof(Student));
    
    Student* student2 = (Student*)(temp);
    
    cout << "Student " << dane.imie  <<" "<< dane.nazwisko << " o numerze albumu: " << dane.nrAlbumu << " oraz ma lat " << dane.wiek << " ma srednia ocen rowna: " << dane.srOcen <<"  Potwierdzenie do zapisu i odczytu!" << endl;
    
    delete student;
    
    
    
    
        return 0;
    }

【问题讨论】:

  • ofs.write((char*)(student), sizeof(Student)); -- 这永远行不通。不能轻易复制的类型不能像这样写入二进制文件。您需要序列化对象,而不仅仅是将原始字节写入二进制文件。
  • 我应该从什么意义上理解?微不足道的可复制?我不明白
  • Student 对象包含std::string。这是一个不可简单复制的对象,因此 Student 类不可简单复制。如果你想要更多的证据,sizeof 做什么?它返回什么值? sizeof 是编译时值。现在假设 std::string 有一个 1000 个字符的 size()sizeof 不知道std::string 将有多少个字符在运行时。因此,整条线没有意义,也不会工作。如果你std::cout &lt;&lt; sizeof(Student); 你得到什么价值?我敢打赌它不是 1000。
  • See thisthis。基本上,您将 data 写入文件,而不是对象。然后在读取时,您读取数据,然后从数据中重新创建对象。

标签: c++ c++11


【解决方案1】:

Student 对象包含std::string 成员。那是一个不可简单复制的对象,因此 Student 类不可简单复制,因此您不能仅通过将字节复制到文件中或从文件中复制字节来简单地将这种类型读取和写入二进制文件。

如果你想要更多的证据,sizeof 做什么?它返回什么值? sizeof 是编译时值。现在假设 std::string 有一个 1000 个字符的 size()。 sizeof 不知道std::string 在运行时会有多少个字符。因此,整行没有意义,也不会工作。

如果您执行以下操作,假设 std::string 成员之一将有 1000 个字符:

std::cout &lt;&lt; sizeof(Student);

你得到了什么价值?我敢打赌它不是 1000 或更高。

这是一个说明问题的快速程序:

#include <type_traits>
#include <string>
#include <iostream>

struct Student{
    std::string imie;
    std::string nazwisko;
    int nrAlbumu;
    int wiek;
    float srOcen;
};

struct Student2{
    char imie[20];
    char nazwisko[20];
    int nrAlbumu;
    int wiek;
    float srOcen;
};

int main()
{
    Student s;
    s.imie = std::string(1000, ' ');
    std::cout << "The number of characters is: " << s.imie.size() << "\n";
    std::cout << "The sizeof(Student) is: " << sizeof(s) << "\n";
    std::cout << "Is Student trivially copyable? " << (std::is_trivially_copyable<Student>()?"Yes":"No") << "\n";
    std::cout << "Is Student2 trivially copyable? " << (std::is_trivially_copyable<Student2>()?"Yes":"No") << "\n";
}

输出:

The number of characters is: 1000
The sizeof(Student) is: 80
Is Student trivially copyable? No
Is Student2 trivially copyable? Yes

请注意,如果您使用 char 数组而不是 std::string,则该结构将变得可轻松复制,然后可用于以您现在正在执行的方式写入二进制文件。

但缺点是您受限于字符数(在我的示例中为 20)。如果您仍想使用std::string,则必须将结构体编写为单独的部分,并按照this answer 的指定相应地处理每个std::string

【讨论】:

    猜你喜欢
    • 2013-12-13
    • 1970-01-01
    • 2015-04-18
    • 1970-01-01
    • 1970-01-01
    • 2023-03-20
    • 2018-08-16
    • 2013-08-24
    • 1970-01-01
    相关资源
    最近更新 更多