Проблема с чтением текстового файла в C++

Я разработал BookStore на основе списка ссылок, в котором атрибуты книги будут храниться в узле и так далее. Кроме того, в конце программы я должен сохранить всю базу данных в текстовый файл (я пробовал двоичное чтение, но, черт возьми, меня убили, и я не смог этого сделать), а затем перезагрузить всю информацию о каждой книге один за другим и сохраните его в узлах и заново создайте LinkList. Теперь сохранение сделано и никаких проблем. Но у меня проблемы с чтением из текстового файла.

Сохранение структуры в файле:::

BookID(int) - BookName(string) - Author(string) - BookType(string) - Copies(long) - Price(long) - '\n' (для перехода к следующей строке)

ПРИМЕР: 1 ObjectOrientedParadigm R.Lafore Coding 5 900 2 ObjectOrientedParadigm R.Lafore Coding 5 900 и т. д.......

Вот функция сохранения.

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

ПРОБЛЕМА:: Когда я начинаю чтение, первая строка читается нормально и сохраняется в списке, но в следующий раз я не могу сделать так, чтобы файл читался со следующей строки, поэтому '\n'. И это создает проблему. Файл снова считывает первую строку, и создается второй узел с теми же данными.

Функция загрузки:

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

БОЛЬШЕ Чтение производится в 1 раз меньше, чем реальная запись. т. е. если .txt имеет запись о 4 книгах, то создаются 3 узла (и информация только о 1-м повторяется в каждом узле), тогда как он должен читать и создавать 4 узла!

Я новичок, буду признателен за любую помощь.


person InamTaj    schedule 03.11.2012    source источник
comment
Какие типы вы будете использовать между ‹› при создании базы данных BookStoreDataBase и книги?   -  person Scooter    schedule 03.11.2012


Ответы (2)


Я бы посоветовал вам получить всю строку, используя std::getline(), а затем использовать класс stringstream, чтобы прочитать все из этого в соответствующие переменные.

person Aniket Inge    schedule 03.11.2012
comment
Подкиньте мне синтаксис. Я уже пробовал это. Просто читает 1-ю строку и все CODE::::::stringstream mystr; файл ifstream (database.txt); while(file››ID››bookName››автор››тип_книги››копии››цена››статус) { mystr››ID››название книги››автор››тип_книги››копии››цена››статус; - person InamTaj; 03.11.2012
comment
просто предложение @deep_ecstasy, можешь опубликовать текстовый файл, который пытаешься прочитать? я дам вам правильное решение - person Aniket Inge; 03.11.2012
comment
ОК решено. 1. Я использовал stringstream mystr (#include‹sstream›) 2. Я пытался прочитать статус книги в функции загрузки, что было НЕПРАВИЛЬНО. 3. правильное условие пока -› пока(файл››ID››названиекниги››автор››тип_книги››экземпляры››цена) ›book_type››копий››цена; ОЧЕНЬ ЛЮБЛЮ ТЕБЯ, MY DeV Bros. ВЫ ПОЛУЧИЛИ ЭТО. СПАСИБОООООООООО! - person InamTaj; 03.11.2012

while (!file.eof()) неправильно, while (file) неправильно. Кажется, что каждый новый программист не понимает, как правильно читать из файла. Если бы я знал, почему, было бы легче советовать новичкам. Основное заблуждение заключается в том, что новички думают, что вы должны проверять конец файла сначала, а затем читать второстепенно. Когда на самом деле вы должны сначала прочитать, а затем посмотреть, не удалось ли прочитать второе.

Это правильный способ чтения из файла

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

Попробуйте это и посмотрите, какие проблемы все еще остаются.

Я только что заметил еще одну проблему, вы пытаетесь прочитать статус, который вы говорите, что это строка, но в вашем описании формата файла нет статуса. Я думаю, это твоя настоящая проблема.

person john    schedule 03.11.2012
comment
Бьерн Страуструп использует while(!file.eof()) - person Aniket Inge; 03.11.2012
comment
Покажите контекст. Использование eof не является незаконным, просто большинство людей используют его неправильно. - person john; 03.11.2012
comment
Есть большая разница между этим while (!file.eof()) { file >> x; ...; }, который мы обычно видим и который является неправильным, и этим file >> x; while (!file.eof()) { ...; file >> x; }, который в порядке, хотя я все же предпочитаю свою версию выше; - person john; 03.11.2012
comment
Сделал по вашему методу, работает нормально, НО читает в 1 раз меньше. Если в файле 3 записи. Он читает 2 книги и создает 2 узла. :( :( - person InamTaj; 03.11.2012
comment
Вы смотрели на проблему статуса, которую я упомянул? Если это не так, то выложите сюда содержимое файла. Трудно помочь, не видя того, что видишь. - person john; 03.11.2012
comment
ОК решено. 1. Я использовал stringstream mystr (#include‹sstream›) 2. Я пытался прочитать статус книги в функции загрузки, что было НЕПРАВИЛЬНО. 3. правильное условие пока -› пока(файл››ID››названиекниги››автор››тип_книги››экземпляры››цена) ›book_type››копий››цена; ОЧЕНЬ ЛЮБЛЮ ТЕБЯ, MY DeV Bros. ВЫ ПОЛУЧИЛИ ЭТО. СПАСИБОООООООООО! - person InamTaj; 03.11.2012