如何使用seekg与字符串输入从二进制文件中获取记录

How to use seekg with string input to get a record from a binary file

本文关键字:二进制文件 获取 记录 输入 何使用 seekg 字符串      更新时间:2023-10-16

我的示例文本文件看起来像这样:

Name: First
Email: first@gmail.com
Name: Second
Email: second@gmail.com

目前我写了一个函数从指定的二进制文件中读取记录:

Staff getARecord (fstream& afile, const char fileName [], int k)
{
    afile.open (fileName, ios::in | ios::binary);
    Staff s;
    afile.seekg ((k - 1) * sizeof (Staff), ios::beg);
    afile.read (reinterpret_cast <char *>(&s), sizeof (s));
    afile.close ();
    return s;
}

Staff是由nameemail域组成的结构。然后我将根据用户输入获取记录:

int k;
cout << "Enter your email: ";
cin >> k;
Staff s = getARecord(afile,"staff.dat",k);

然后我已经成功读取数据,如果用户的输入是数字(1和2现在,因为我只有2条记录)为了seekg功能,我怎么能检索相同的结果,如果用户输入电子邮件而不是记录号?

正如评论中提到的,有一个严重的问题是你将数据加载到Staff结构中的方式:afile.seekg(...); afile.read(...);行很奇怪:seekg不应该像你期望的那样工作。由于您的文件是一个文本文件,您应该使用文本技术:操作符>>getline方法。

如果你真的想直接从文件中加载Staff项,你可以重载operator>>:(这只是一个例子,它应该得到改进)

struct Staff{
    string name, email;
};
istream& operator>>(istream& is, Staff& staff)
{
    string s;
    while(is >> s && s != "Name:"); // Look for "Name:"
    staff.name = "";
    while(is >> s && s != "Email:"){ // Look for "Email:"
        staff.name += s + " "; // Load name (if multiple words)
    }
    staff.email = s; // Load email
    // Handle errors
    if(/* we couldn't load staff */)
        is.setstate(std::ios::failbit);
    return is;
}

然后,如果您想进行搜索,您别无选择,只能从头开始读取文件:

Staff staff;
// Search by id
for(int i=0 ; i<=k ; i++)
    afile >> staff;
return staff;
// Search by email
while(afile >> staff){
    if(staff.email == email)
        return staff;
}
return /*Error*/;