在c++中顺序地从二进制文件中读取结构体
sequentially reading a structs from binary file in C++
我想写一个程序,当程序正在执行一个操作(例如:搜索、更新或添加),应该是直接访问。这个项目不应依次读取所有记录以达到一条记录。
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
struct Student{
int Id;
int Money;
int Age;
char name[15];
};
void main(){
Student buffer;
ofstream BinaryFile("student", ios::binary);
ifstream WorkerText("worker.txt");
//-------------------------------------------------------------------------------------------------------------
while( WorkerText.good() ){
WorkerText>> buffer.Age >> buffer.name >> buffer.name >> buffer.name;
BinaryFile.write( (char *) &buffer, sizeof(Student) );
}
BinaryFile.close();
//-------------------------------------------------------------------------------------------------------------
ifstream ReadBinary( "student", ios::binary | ios::out );
while( BinaryFile.good() ){
ReadBinary.read((char*)&buffer,sizeof(Student));
cout<<buffer.Age;
}
//-------------------------------------------------------------------------------------------------------------
system("pause");
}
我卡在这里,我不能按顺序阅读我怎么解决这个
如果文件包含相同大小的结构,或者使用某些索引表,则可以跳过顺序读。
对于相同尺寸的结构体:
void ReadStudent(istream &src, Student &dst)
{
src.read(&dst, sizeof(dst));
}
void GoToStudentIndex(istream &src, size_t idx)
{
src.seekg(idx * sizeof(Student), is.beg);
}
上面的函数假设您按照如下方式写入数据:
void WriteStudent(ostream &dst, const Student &src)
{
dst.write(&src, sizeof(src));
}
当您打开学生文件输入时,您正在使用"out"模式:
ifstream ReadBinary( "student", ios::binary | ios::out );
^^^^^^^^ ^^^^^^^
试试这个:
ifstream ReadBinary("student", ios::binary);
ifstream
构造函数已经以输入模式(ios::in
)打开文件。
有三个选项可以避免顺序读取:
- 有分隔的记录,按键排序存储,并使用分割
- 有固定大小的记录,按键排序存储,并使用分割
- 拥有比数据文件小得多的单独索引文件(key =>数据文件中的偏移量),先预加载它,然后由偏移量直接读取。
当我们想要进行搜索(和随后的更新),但在平面文件中顺序存储记录时,您需要有外部索引来帮助您直接访问所需的记录!在这个例子中,你想按名字搜索学生然后更新记录,你可以这样做:
// Store in map name and the position of record
std::map name2offset;
void writeRecord(const Student& student)
{
name2offset[string(student.name)]=BinaryFile.tellp();
BinaryFile.write(reinterpret_cast<char*>(&student), sizeof(Student));
}
// Return true if updated successfully else false.
bool update(const string& name, Student &newRecord)
{
std::map<char,long>::iterator itr = name2offset.find(name);
if (itr != name2offset.end()) {
BinaryFile.seekp(itr->second);
BinaryFile.write(reinterpret_cast<char*>(&newRecord), sizeof(Student));
return true;
}
return false;
}
这些都假设你的结构体是固定大小的(在你的例子中就是这样)。
相关文章:
- 如何在 c++ 中将二进制文件读取为字符串
- 从二进制文件读取到数组:前面的任意数字
- 提升二进制文件读取错误不支持的版本
- 无法将二进制文件读取到 std::vector<std::byte> 中C++
- 提升序列化在从二进制文件读取时引发异常
- 从二进制文件 C++ 读取的字符串数组写入
- 将二进制文件读取到 std::vector<bool>
- 将fortran生成的二进制文件读取到C++中的带符号整数数组中
- 将从二进制文件读取的字符串转换为整数
- 从/到C 的二进制文件读取和写作整数
- 通过将结构信息从二进制文件读取到数组中,然后返回到文件C
- 将 int 的二进制文件读取到字符串 c++
- 将结构从二进制文件读取到链表,导致无限循环
- 将二进制文件读取到向量元素的地址中
- c++从二进制文件读取/写入类
- Python:将二进制文件读取到一个结构中,然后拆包
- 从二进制文件读取/写入十六进制字节
- 简单的 C++ 二进制文件读取
- 从二进制文件 c++ 读取 16 位整数
- 如何优化c++二进制文件读取