Jim
Jim

Reputation: 171

C++ Array structure

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

Upvotes: 0

Views: 121

Answers (3)

Eryk Arojan
Eryk Arojan

Reputation: 1

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

   }

Upvotes: 0

David G
David G

Reputation: 96865

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"));

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 311146

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;

Upvotes: 2

Related Questions