InamTaj
InamTaj

Reputation: 276

Text File Reading Issue in C++

I have designed a linklist based BookStore in which book's attributes will be stored in a node & so on. Plus at the end of program, I have to save all database into text file (I tried binary reading but damn I got me killed & couldn't do it) & then reload all info, of each book one by one & store it in nodes & re-make the LinkList. Now saving is done & no issue at all. But Im having issues in reading from text file.

Saving structure in file is:::

BookID(int) - BookName(string) - Author(string) - BookType(string) - Copies(long) - Price(long) - '\n' (to go to next line)

EXAMPLE: 1 ObjectOrientedParadigm R.Lafore Coding 5 900 2 ObjectOrientedParadigm R.Lafore Coding 5 900 and so on......

Here is the saving function.

bool BookStoreDataBase<mytype>::save_all_data()
{
    if(!is_Empty()) //if list is not empty
    {
        BOOK<mytype> *temp = head;   //created a copy of head
        ofstream file("database.txt", ios_base::app); //created file, to write at the end (append)
        while(temp != tail) //while list ends
        {
            file<<temp->ID<<' '<<temp->bookName<<' '<<temp->author<<' '<<temp->book_type<<' '<<temp->copies<<' '<<temp->price<<' ';  //write all info
            temp = temp->next; //move temp to next node
        }
        file<<temp->ID<<' '<<temp->bookName<<' '<<temp->author<<' '<<temp->book_type<<' '<<temp->copies<<' '<<temp->price<<' '; //for last book's info
        return true; //to confirm sucessfull writing
    }
    else //if list is empty
    {
        return false; //to confirm error in writing
    }
}

PROBLEM:: When I start reading, first line is read fine & stored in list, but for the next time, I can't make file to read from the next line, hence '\n'. & that creates the problem. File again reads the first line & 2nd node is created with same data.

Loading Function:

void BookStoreDataBase<mytype>::load_all_data()
{
    int ID;         //variable to store ID of a book
    string bookName;//string to store name of a book
    string author;  //string to store name of author of book
    string book_type;//string to store type of a book
    long copies;    //variable to store no. of copies a book
    long price;     //variable to store price of a book
    string status;  //to store status of a book, either its in stock or not


    ifstream file("database.txt");
    while(file) //I have tried file.eof but its not working, don't know why
    {
        file>>ID>>bookName>>author>>book_type>>copies>>price>>status; //read file

        BOOK<mytype> *temp = new BOOK<mytype>(0, 0, bookName, author, book_type, copies, price);  //create a new node in memory and save all the data

        if(is_Empty()) //if list is empty, then make 1st node
        {
            head = tail = temp;
        }
        else //other wise make the next node
        {
            tail->next = temp;
            temp->prev = tail;
            tail = temp;
        }
    }
}

MOREOVER Reading is done 1 time less than the real record. i.e. If .txt has record of 4 books, then 3 nodes are created, (& info of only 1st is repeated in every node), whereas it should read & create 4 nodes!

I'm a beginner, any good help will be much appreciated.

Upvotes: 0

Views: 791

Answers (2)

john
john

Reputation: 88027

while (!file.eof()) is wrong, while (file) is wrong. Seems that every new programmer fails to understand the correct way to read from a file. I wish I knew why, it would be easier to advise newbies. The basic misunderstanding seems to be that newbies think you should test for end of file first and then read second. When really you should read first and then see if the read failed second.

This is the correct way to read from a file

while (file >> ID >> bookName >> author >> book_type >> copies >> price >> status)
{
}

Try that and see what problems still remain.

I've just noticed another problem, you try to read the status which you say is a string, but in your description of the file format there is no status. That's your real problem I think.

Upvotes: 1

Aniket Inge
Aniket Inge

Reputation: 25725

I would suggest you get the whole line using std::getline(), and then use stringstream class to read in everything from that into the respective variables.

Upvotes: 2

Related Questions