0

I have made a book storage program in c++. It is program which loops over 3 times so the user can input 3 books but now I want user to pick the amount of book user wants to enter and I have no clue how to do it. It would be helpful and here is my code

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

struct Book{
    string name;
    int release;
}Issue[3];

int main(){
    //local variable
    int i;
    string release_dte;
    //interface
    cout << "Welcome to Book Storage CPP" << endl;
    //for handler
    for (i = 0; i < 3; i++){
        cout << "Book: ";
        getline(cin, Issue[i].name);
        cout << "Release Date: ";
        getline(cin, release_dte);
        Issue[i].release = atoi(release_dte.c);
    }
    cout << "These are your books" << endl;
    for ( i = 0; i < 3; i++){
        cout << "Book: " << Issue[i].name << " Release Date: " << Issue[i].release << endl;
    }
    system("pause");
    return 0;
}

3 Answers 3

2

The best way is to use std::vector. For example

#include <vector>
//...

struct Book{
    string name;
    int release;
};

int main()
{
   size_t issue_number;

   std::cout << "Enter number of books: ";
   std::cin >> issue_number;

   std::vector<Book> Issue( issue_number );
//...    

Otherwise you should dynamically allocate the array yourself. For example

Book *Issue = new Book[issue_number];

and in the end of the program you need to release the allocated memory

delete []Issue;
Sign up to request clarification or add additional context in comments.

Comments

0

Extending (and critiquing) Vlad's answer, you won't need the amount of the books beforehand if you utilize stream iterators. You can also overload the stream extractor for Book so that the extraction is correctly implemented by the iterators:

std::istream& operator>>(std::istream& is, Book & b)
{
    if (!is.good())
        return is;

    std::string release_date;

    if (std::getline(is >> std::ws, b.name) &&
        std::getline(is >> std::ws, release_date))
    {
        b.release = std::stoi(release_date);
    }

    return is;
}

And later in main() you would still use std::vector<Book>, only using the iterator overload of the constructor to generate the objects:

int main()
{
    std::vector<Book> Items(std::istream_iterator<Book>{std::cin},
                            std::istream_iterator<Book>{});

    ...
}

For printing you can overload the inserter which implements the logic for printing:

std::ostream& operator<<(std::ostream& os, const Book & b)
{
    return os << "Book: "          << b.name << '\n'
              << " Release Date: " << b.release;
}

And invoking this inserter using std::copy:

std::copy(Items.begin(), Items.end(),
    std::ostream_iterator<Book>(std::cout << "These are your books: \n", "\n"));

Comments

0
   #include <iostream>
   #include <string>
   #include <vector>

   using namespace std;

   struct Book {
          string name;
          int release;
          Book(string _name, int _release) {
                 name = _name;
                 release = _release;
          }
   };

   int main() {
          vector<Book> books;
          string name;
          int release;

          while(cin >> name >> release) {
                 books.push_back(Book(name,release));
          }

          for(int i=0; i<(int)books.size(); ++i) {
                 cout << books[i].name << " - " << books[i].release << endl;
          }

          return 0;

   }

1 Comment

This code won't work for the OP's purposes as it requires that release be an integer, not a string. Also, the name might take the last name as well which the >> operator won't be able to extract. Your example has a lot of room for improvement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.