0

I am writing a library system for a small project and I have this code so far: The first thing I'm trying to show is the show menu so the user can choose and once the user choses to register a new book, the registerBook(bookInfo) should print all the questions and the data would be stored in the file that I created. However, the code is not doing this and the data that I put in when registerBook is processed is not stored in the text file. Could you someone tell me what I'm missing or why it's not storing the data?

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

}

void showMenu(BookShelf bookInfo) {
    int option;
    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);
    }

}

int main() {

    ofstream library("mylibrary.txt", ios::app);


    BookShelf bookInfo;


    showMenu(bookInfo);

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

    ifstream bank("mylibrary.txt", ios::in);//to read the file that I previously created
    BookShelf bookInfo;
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;

}

Emily
  • 21
  • 7
  • There is no `cout` here `< – Error - Syntactical Remorse Aug 14 '17 at 15:04
  • 2
    You need to use `cin.ignore()` to consume and discard newlines, and `cin.clear()` to reset error bits. Hopefully someone can find a good duplicate question - there are loads, but none great. – Useless Aug 14 '17 at 15:07
  • `std::istream::get()` unlike `std::istream::getline()` does not extract the delimiter (by default newline( character. Also you shall **always** verify that input was successful before using the result, e.g., using `if (std::cin.get(name, 50)) { /* use result */ }` – Dietmar Kühl Aug 14 '17 at 15:09
  • 1
    1) Use `std::string` instead of character arrays. 2) Use `std::getline` for inputting text that is terminated by a newline (or other delimiter). – Thomas Matthews Aug 14 '17 at 15:47
  • Could it be possible that the size of the array is not big enough? I typed in "To Kill a MockingBird" and it printed out all the other questions but when I typed in "tokillamockingbird" it went on to the next question. – Emily Aug 14 '17 at 16:19

2 Answers2

0

Try this code:

#include <iostream>
#include <fstream>
#include <iomanip>

using namespace std;

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

int main() {
    ofstream books("My Library Books.txt", ios::app); //creating a file
    myBook 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;

    return 0;
}

I have changed name and author to string and using std::getline instead of cin.get.

Reference here.

Praveen Kumar
  • 483
  • 1
  • 5
  • 12
  • Thank you! why wouldn't a char work? just for future projects. does the size array that I set 50, too short for say "To Kill a MockingBird" ? – Emily Aug 14 '17 at 22:47
  • The `size of char array` you are using is fixed. This will create problem if you have a name which is more than the assigned size. So its always preferred to use `string` – Praveen Kumar Aug 15 '17 at 02:44
  • If you still want to use `char array`, then just add `cin.ignore();` after every `cin.get()` function call in your code, it will work out for you. But then, if the input goes beyond 50 `char`, then it will override the values of next parameters. So, either put a limit to number of characters any user can enter of use `string`. – Praveen Kumar Aug 15 '17 at 02:54
  • Thank you all it worked! Now I'm trying to move forward with the project! – Emily Aug 15 '17 at 11:42
0

You need to insert cin.ignore() everytime before you ask for more input like so:

int main() {
   ofstream books("My Library Books.txt", ios::app); //creating a file  
   myBook bookInfo;
   cout << "Enter the book's name: " << endl;
   cin.get(bookInfo.name, 50);
   cout << "Enter the author of the book: " << endl;
   cin.ignore(); // <--
   cin.get(bookInfo.author, 50);
   cout << "Enter the books ID: " << endl;
   cin.ignore(); // <--
   cin >> bookInfo.ID;
   cout << "Enter number of the book's copies available: " << endl;
   cin.ignore(); // <--
   cin >> bookInfo.copiesNumber;
   cout << "Enter the book's price: " << endl;
   cin.ignore(); // <--
   cin >> bookInfo.price;

   return 0;
}
Devin L.
  • 437
  • 2
  • 12