如何在 c++ 中将二进制文件读取为字符串

How to read binary file as string in c++

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

在二进制文件中,有一些信息是三个学生的学生证,姓名和GPA。我想读它们。id 是整数类型,GPA 是浮点类型。name 是字符串类型,大小不是固定的,因为 name 的大小彼此不同。我想在学生班级的功能中获取每个学生的ID,姓名和GPA。

可能,我认为我在加载名称时遇到问题。 我想知道如何解决它。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
class Student {
private:
int id;
string name;
float GPA;
string line;
public:
Student() {};
Student(string line_) :line(line_) {  };
int get_id();
string get_name();
float get_GPA();
void save_bi(ofstream &of);
void load_bi(ifstream &inf);
void save_txt(ofstream &of);
void print();
};

void Student::load_bi(ifstream &inf)
{
inf.read((char*)&id, sizeof(id));
inf.read((char*)&name, sizeof(name));
inf.read((char*)&GPA, sizeof(GPA));
//a.push_back(name);
}

int main()
{
ifstream inf;
inf.open("student_data.bin", ios::in | ios::binary);
if (!inf.is_open())
cout << "file open failure." << endl;
Student A;
A.load_bi(inf);
A.print();
Student B;
B.load_bi(inf);
B.print();
Student C;
C.load_bi(inf);
C.print();
inf.close();

return 0;
}

这是错误消息。

inline void _Container_base12::_Orphan_all() noexcept
{   // orphan all iterators
#if _ITERATOR_DEBUG_LEVEL == 2
if (_Myproxy != nullptr)
{   // proxy allocated, drain it
_Lockit _Lock(_LOCK_DEBUG);
for (_Iterator_base12 **_Pnext = &_Myproxy->_Myfirstiter;
*_Pnext != nullptr; *_Pnext = (*_Pnext)->_Mynextiter)
(*_Pnext)->_Myproxy = nullptr;
_Myproxy->_Myfirstiter = nullptr;
}
#endif /* _ITERATOR_DEBUG_LEVEL == 2 */
}

引发异常:读取访问冲突。 _Pnext 0x13AED64。

序列化结构的简单示例:

class Student
{
int id;
string name;
float GPA;
string line;
public:
void binary_write(std::ostream& out) const;
void binary_read(std::istream& input);
};
void Student::binary_write(std::ostream& out) const
{
out.write(&id, sizeof(id));
std::string::size_type length(name.length());
out.write(&length, sizeof(length));
out.write(name.data(), length);
out.write(&GPA, sizeof(GPA));
length = line.length();
out.write(line.data(), length);
}
void Student::binary_read(std::istream& input)
{
input.read(&id, sizeof(id));
std::string::size_type length;
input.read(&length, sizeof(length));
char * temp = new char[length];
input.read(temp, length);
name = std::string(temp);
input.read(&GPA, sizeof(GPA));
delete[] temp;
input.read(&length, sizeof(length));
temp = new char[length];
input.read(temp, length);
line = std::string(temp);
delete [] temp;
}

上面的代码使用写入字符串长度的技术,后跟字符串内容。 读取包括使用临时缓冲区,然后将文本读入缓冲区并从缓冲区创建std::string

还有其他方法可以在字符串中读取(在C++参考中搜索"c ++ 字符串输入迭代器"(,但这说明了这一点。

编写指针和std::string包含指针的问题在于,不能保证操作系统会在每次调用时将程序加载到内存中的完全相同位置。

binary_write函数声明为const,因为它不会更改任何Student数据成员。 这种技术称为"常量正确性"。 在互联网上搜索其定义。

class的默认可访问性是私有的,因此我从声明变量的部分中删除了private