1

我正在尝试编写一个程序,当程序正在执行操作(例如:搜索、更新或添加)时,它应该是直接访问。程序不应按顺序读取所有记录以达到一条记录。

 #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");
}

我卡在这里我无法按顺序阅读我该如何解决这个问题

4

4 回答 4

1

仅当文件包含相同大小的结构或使用某些索引表时,您才可以跳过顺序读取。

对于相同大小的结构:

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));
}
于 2013-03-16T17:47:52.873 回答
0

当您打开学生文件进行输入时,您正在使用“out”模式:

ifstream ReadBinary( "student", ios::binary | ios::out );  
^^^^^^^^                                      ^^^^^^^

试试这个:

ifstream ReadBinary("student", ios::binary);  

构造函数已在输入模式 ( )ifstream中打开文件。ios::in

于 2013-03-16T17:39:47.113 回答
0

有三个选项可以避免顺序读取:

  1. 有分隔的记录,按键排序存储它们并使用二分法
  2. 有固定大小的记录,按键排序存储它们并使用二分法
  3. 拥有比数据文件小得多的单独索引文件(key => 数据文件中的偏移量),先预加载它并用于通过偏移量直接读取。
于 2013-03-16T17:55:05.393 回答
0

当我们想要进行搜索(和后续更新)但将记录顺序存储在平面文件中时,您需要有外部索引来帮助您直接访问所需的记录!假设在这种情况下您想按姓名搜索学生然后更新记录,您可以执行以下操作:

// 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;
}

这些都假设您的结构是固定大小的(在您的示例中)。

于 2013-03-16T18:23:58.327 回答