Member 13363286 Ответов: 3

Создание файла и добавление данных C++


Я пишу библиотечную систему для небольшого проекта, и до сих пор у меня есть такой код: первое, что я пытаюсь показать, - это меню show, чтобы пользователь мог выбрать, и как только пользователь решит зарегистрировать новую книгу, registerBook(bookInfo) должен напечатать все вопросы, и данные будут сохранены в файле, который я создал. Однако код этого не делает, и данные, которые я вставляю при обработке registerBook, не хранятся в текстовом файле. Не могли бы вы кто-нибудь сказать мне, что я упускаю или почему он не хранит данные?

Что я уже пробовал:

<pre lang="c++"><pre>#include <fstream>
#include <iomanip>
#include <iostream>
using namespace std;

struct BookShelf{
    string name;
    string author;
    int ID;
    int copiesNumber;
    float price;
};

void registerBook(BookShelf *bookInfo) {
    
    cout<<"Enter the book's name: "<<endl;
    std::getline(cin, bookInfo->name) ;
    cout<<"Enter the author of the book: "<<endl;
    std::getline(cin, bookInfo->author);
    cout<<"Enter the books ID: "<<endl;
    cin>>bookInfo->ID;
    cout<<"Enter number of the book's copies available: "<<endl;
    cin>>bookInfo->copiesNumber;
    cout<<"Enter the book's price: "<<endl;
    cin>>bookInfo->price;
    
    
}

void searchBook(BookShelf bookInfo) {
    int choice;
    cout<<"Would you like to search for the book by"<<endl;
    cout<<"1)Book Name"<<endl;
    cout<<"or"<<endl;
    cout<<"2)Book ID"<<endl;
    cin>>choice;
    if(choice==1) {
        string searchName;
        cout<<"Enter book's name:"<<endl;
        std::getline(cin, searchName); //why does the program end here? it outputs the quetsion and the programe ends.
        
    }
    else if (choice==2) {
        int bookID;
        cout<<"To update the book enter book's ID:"<<endl;
        cin>>bookID;
        //create for loop to find a match for the entered book's ID, if found
    }
    
}

void updateBook(BookShelf bookInfo) {
    int bookID;
    cout<<"Enter book's ID to update: "<<endl;
    cin>>bookID;
    
    
}

void deleteBook(BookShelf bookInfo) {
    int deleteID;
    cout<<"Enter book's ID:"<<endl;
    cin>>deleteID;
    
    
}

void borrowBook(BookShelf bookInfo) {
    int borrowName;
    cout<<"Enter name of the book you want to borrow:"<<endl;
    cin>>borrowName;
    //use for loop to search if the entered name matches any of the available book names in the file, if it is available output "book is available to borrow", if no matches were found then output"no matches were found"
    
}

void exitPrograme(BookShelf bookInfo) {
    cout<<"You exited the programe. See you next time!"<<endl;
    
}



int main() {
    
    ofstream trylibrary("fakelibrary.txt", ios::in);
    
    BookShelf bookInfo;
    int option;
    do {
        
        cout<<"What would you like to do?"<<endl;
        cout<<"1)Register new Book"<<endl;
        cout<<"2)Search for book"<<endl;
        cout<<"3)Update a book"<<endl;
        cout<<"4) Delete a book"<<endl;
        cout<<"5)Borrow a book"<<endl;
        cout<<"6)Exit the programe"<<endl;
        cin>>option;
        if(option==1) {
            registerBook(&bookInfo);
        }
        else if(option==2) {
            searchBook(bookInfo);
        }
        else if(option==3) {
            updateBook(bookInfo);
            
        }
        else if(option==4) {
            deleteBook(bookInfo);
        }
        else if(option==5) {
            borrowBook(bookInfo);
        }
        else if(option==6) {
            exitPrograme(bookInfo);
        }
        else {
            cout<<"Please Choose an option."<<endl;
        }
    }
    while(option!=6);
    return 0;

    //trylibrary<<bookInfo.name<<" "<<bookInfo.author<<" "<<bookInfo.ID<<" "<<bookInfo.copiesNumber<<" "<<bookInfo.price<<endl;
}

Kornfeld Eliyahu Peter

Вы использовали отладчик?

3 Ответов

Рейтинг:
2

Richard MacCutchan

while(library>>bookInfo.name>>bookInfo.author>>bookInfo.ID<<bookInfo.copiesNumber<<bookInfo.price) {
    cout<<left<<setw(50)<<bookInfo.name<<"   "<<left<<setw(20)<<bookInfo.author<<"   "<<left<<setw(7)<<bookInfo.ID<<"   "<<endl;
}

Утверждения, подобные приведенным выше, неизбежно вызовут проблемы. Прочитайте и запишите свои элементы по одному на строку кода, и тогда вы сможете увидеть, где что-то идет не так. И вместо того, чтобы пытаться написать всю программу за один раз, делайте это поэтапно. Начните с кодирования части, которая читает и записывает файлы,и используйте некоторые примеры данных для проверки. Затем добавьте каждый новый метод по одному, проверяя каждый по ходу.


Member 13363286

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

Richard MacCutchan

Вы должны прочитать все данные из входного файла в начале программы и создать коллекцию (вектор, карту и т. д.) записей. Затем используйте меню для добавления, удаления, изменения записей по выбору пользователя. Когда пользователь выбирает опцию quit, вы записываете все обновленные записи в выходной файл.

Member 13363286

я могу иметь оба потока и руслового? или убрать потока после того, как файл был создан? не могли бы вы подробнее рассказать о векторе и карте?

Richard MacCutchan

К сожалению, здесь нет места, чтобы предоставить полный учебник. Google найдет для вас образцы и учебные пособия по каждому предмету, который вам нужно изучить. Но прежде чем вы начнете писать код, вам действительно нужно четко представить себе свой дизайн. И лучший способ сделать это-написать это на бумаге ясным языком.

Рейтинг:
1

KarstenK

В C++ struct тип данных-это параметры копирования, поэтому при вызове функции создается новый экземпляр (с скопированным содержимым).

Вам нужно работать со ссылочными типами. Поэтому вы должны использовать указатели на такие структуры, как:


// implementation
void registerBook(BookShelf *pbookInfo) {
 
    cout<<"Enter the book's name: "<<endl;
    std::getline(cin, pbookInfo->name) ;
    // ...
}
// call
registerBook( &bookInfo ); // & operator gives the pointer to the object
Используйте отладчик, чтобы лучше понять его.


Member 13363286

Я должен вызвать функцию в главном правом углу? Я пробовал использовать указатели, но вводимые пользователем данные не сохраняются в созданном файле. Есть ли что-то неправильное в моем коде для создания файла и храню ли я данные или нет? Спасибо!

Jochen Arndt

Вы должны сделать то же самое для все функции, в которых передается параметр книжной полки и который должен быть обновлен.

Но вы можете использовать ссылки вместо указателей (см. Мой другой комментарий).

И вы должны раскомментировать операции записи.

Jochen Arndt

Вы уловили источник проблемы, +5.

Вы уже говорите о рекомендациях. Поэтому здесь было бы проще использовать их вместо указателей, потому что для этого требуется только изменить объявление функции на

void registerBook(BookShelf& pbookInfo)
при использовании указателей требуется редактирование всех обращений и вызовов функции.

Кроме того, ссылки должны быть предпочтительными для требуемых параметров, потому что они не могут быть нулевыми, как указатели.

Member 13363286

дело в том, что мы еще не научились пользоваться ссылками. Вот почему я использовал указатели. Не могли бы вы взглянуть на функцию registerBook ()? когда я выбираю 1) зарегистрировать новую книгу, Первый вопрос распечатывается, а второй сразу же следует за ним, и я могу ввести ответ только начиная со второго вопроса. Кроме того, если бы вы могли подсказать мне, как читать данные внутри файла, который я создал, и искать их.
Я думаю, что мне следует использовать цикл for, когда я ищу книгу, используя либо имя, либо идентификатор, но я не уверен, как это сделать. Большое вам спасибо!

Jochen Arndt

Затем используйте указатели.

Проблема с пропущенным вводом заключается в том, что вы используете

cin>>option;
в main() и аналогично в других местах.
Это будет считывать числовое значение и сохранять его при нажатии клавиши возврата. Но сам ключ возврата все равно будет находиться в очереди ввода. При последующем вызове std::getline() он получит код возврата из ввода и ничего не сохранит (пустой ввод).

Решение:
Вы должны очистить вход после чтения или всегда использовать std:: getline (). Я предпочитаю последний способ. Вы можете написать функцию для чтения числового ввода:
int readInt()
{
std::string buf;
std::getline(cin, buf);
// Should check for valid number here
return atoi(buf.c_str());
}

Рейтинг:
0

CPallini

Для сохранения (загрузки) объектов в файл (из файла) их необходимо сериализовать. Смотрите, например: Сериализации и десериализации - стандарт C++[^].