read and rewrite lines in file in C++

I need little help with my homework in C++. My task is to write a function for borowing books form library called borrow(name,surname, student_id, book_id), which will connect information of borrowed book's ID and student's informations in the file.

File looks like this:
1
2
3
4
5
6
7
8
John Jackson 45 0

Michael Gregory 34 56

Ann Cawitch 23 0

Chris Lamb 34 50
...

First two words are name and surname of students. First number represents student's ID and second one represents ID of book. If ID of book is 0, it means that student hasn't borrowed book yet, so he can borrow some book. If ID of book is not 0, it means that student can't borrow a book until he returns the old one. So, when student borrows book, ID of book in file should change from zero to some number

This is my code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void borrow(string name, string surname, int student_id,int book_id )
{

    string a;
    string b;
    int c=0;
    int d;
    fstream f2;
    f2.open("students.txt", ios::out |ios::in);
    while (f2 >> a >> b >> c>> d)
    {
        if (a==name && b==surname && c==student_id)
        {
            if (d==0)
            { 
                f2 <<name<<" "<<surname<<" "<<student_id<<" "<<book_id<<"\n";
                cout<<" Book is borrowed successfully"<<endl;
                f2.close();
                break;
            }
            else 
            {
                cout<<" Student can't boorow book because he has already borrowed one."<< endl;
                break;
            }
        }
        else (c==0);
    }
    if (c==0)  cout<<" Student isn't sign up  library."<<endl;  
}

Whenever I call function (for example borrow(John, Jackson,45,15)), I get answer "Student isn't sign up library."

Am I on a right path? Can you help me make this code to work?
Last edited on
pass name and surname by const-reference.
Changing a value in a file isn't that simple.
I would probally just read the whole thing, change what you want and write everything back out.
Here is how one could do it (however, it is by no means perfect!)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
void borrow(
    const string& name,
    const string& surname,
    int student_id,
    int book_id
            )
{
    ifstream file("students.txt");
    if (!file) {
        cout << "Could not open file 'students.txt'\n";
        return;
    }
    string line;
    vector<string> content;
    bool found = false; //  flag to check existance
    while (getline(file, line)) {
        if (line == "") continue;     // ignore empty lines
        istringstream stream{ line };
        string a, b;
        int sID, bID;
        stream >> a >> b >> sID >> bID;
        if (!stream) cout << "Invalid file entry:\n" << line << '\n';

        if (a == name && b == surname && sID == student_id) {
            found = true;
            if (!bID) {
                content.push_back(a + " " + b + " " +
                                 to_string(sID) + " " + to_string(book_id));
                cout << "Book borrowed successfully\n";
            } else {
                content.push_back(line);
                cout << "Student can't boorow book, "
                     << "because he has already borrowed one.\n";
            }
        }
        else
            content.push_back(line);
    }
    if (!found) cout << "Student does not exist in file.\n";
    file.close();
    ofstream ofile("students.txt");
    for (const auto& line : content)
        ofile << line << '\n';
}
Thanks for help but your code does not compile in VS 2012. The problem is with following line of code
istringstream stream{ line };
Probably these curly brackets should be replaced with standard parenthesis.
I tried that and code compiled, but another problem appears. Every time I try to run the program I get message "Invalid file entry". I can't guess why is that so.
Last edited on
Yes, if that doesn't work with your compiler ,the easiest solution is using the standard "()".
If you are interested in this, google: C++11 uniform initialization
You are right, my code is not that great. Remove the following lines and it should work (they are not needed):
1
2
if (line == "") continue;     // ignore empty lines
if (!stream) cout << "Invalid file entry:\n" << line << '\n';
Last edited on
Thanks, it is very good now
Topic archived. No new replies allowed.