Pewds
Pewds

Reputation: 65

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

My sample text file look something like this:

Name: First
Email: [email protected]

Name: Second
Email: [email protected]

Currently I wrote a function to read a record from specified binary file:

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 is a structure consist of name and email field. Then I will get the record based on the user input:

int k;

cout << "Enter your email: ";
cin >> k;

Staff s = getARecord(afile,"staff.dat",k);

Then I've successfully read the data if user's input is numeric(1 and 2 for now since I only have 2 records) for the sake of seekg function, how can I retrieve the same result if user input the email instead of record number?

Upvotes: 0

Views: 843

Answers (1)

styko
styko

Reputation: 701

As mentioned in the comments, there are serious concerns about the way you are loading data into your Staff structure: the lines afile.seekg(...); afile.read(...); are weird: seekg should not work as you expect. As your file is a text file, you should use text techniques: the operator >> or the getline method.

If you really want to load a Staff item directly from the file, you can overload operator>>: (this is just an example, it should be improved)

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

Then, if you want to do a search, you have no choice but to read the file from the beginning:

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

Upvotes: 0

Related Questions