Reputation:
I have a structured a data type called bookStruct and books is the name of the variable associated with the bookStruct data type. book[10] is the array that is 10 characters long and has 4 characters of data, meaning book[0] to book [3] have datas in them when the rest are empty (o values). Now I want to print the datas that are availabe already in the array and not print the ones that are empty otherwise 0. I tried the below code, with no luck.What am I doing wrong here?
for (int i=0;i<MAX_BOOKS && books[i]!='\0';i++)
{
cout << "Book Title: " << books[i].bookTitle << endl;
cout << "Total Pages: " << books[i].bookPageN << endl;
cout << "Book Review: " << books[i].bookReview << endl;
cout << "Book Price: " << books[i].bookPrice<< "\n\n" << endl;
}
here is the declaration for book struct
struct bookStruct
{
string bookTitle;
int bookPageN;
int bookReview;
float bookPrice;
};
bookStruct books[10];
Upvotes: 9
Views: 64383
Reputation: 12751
Use a friend function to customize your print. Then just trigger a loop on your records. C++20 required for using ranges.
struct bookStruct
{
std::string bookTitle;
int bookPageN;
int bookReview;
float bookPrice;
friend std::ostream& operator<<(std::ostream& os, const bookStruct& book)
{
if (!book.bookTitle.empty()) //Ensure title exists.
{
return os << std::endl << "Book Title: " << book.bookTitle << std::endl
<< "Total Pages: " << book.bookPageN << std::endl
<< "Book Review: " << book.bookReview << std::endl
<< "Book Price: " << book.bookPrice << std::endl;
}
else
{
return os;
}
}
};
int main()
{
//Input - four records
const std::vector<bookStruct> books{ {"book1",200,2,2000.00}, {"book2",400,4,4000.00},
{"",0,0,0.0},{"",0,0,0.0} };
std::ranges::for_each(books, [](auto book) {std::cout << book; });
return 0;
}
Upvotes: 0
Reputation: 41
#include <iostream>
using namespace std;
struct bookStruct
{
string bookTitle;
int bookPageN;
int bookReview;
float bookPrice;
void set(string t,int pn,int r,float pr){
bookTitle = t;
bookPageN = pn;
bookReview = r;
bookPrice = pr;
}
};
ostream& operator << (ostream& os, const bookStruct& book)
{
return os << "Title: " << book.bookTitle <<
" Pages: " << book.bookPageN <<
" Review: " << book.bookReview
<< " Price:" << book.bookPrice << endl;
}
int main() {
bookStruct books[10];
for(int i =0;i<10;i++){
books[i].set("Book " + to_string(i),i*20,i,(float) i*54);
}
for(int i=0;i<10;i++){
cout << books[i];
}
return 0;
}
Output:::
Title: Book 0 Pages: 0 Review: 0 Price:0
Title: Book 1 Pages: 20 Review: 1 Price:54
Title: Book 2 Pages: 40 Review: 2 Price:108
Title: Book 3 Pages: 60 Review: 3 Price:162
Title: Book 4 Pages: 80 Review: 4 Price:216
Title: Book 5 Pages: 100 Review: 5 Price:270
Title: Book 6 Pages: 120 Review: 6 Price:324
Title: Book 7 Pages: 140 Review: 7 Price:378
Title: Book 8 Pages: 160 Review: 8 Price:432
Title: Book 9 Pages: 180 Review: 9 Price:486
Upvotes: 0
Reputation: 24133
Overload the output operator. E.g:
struct Book {
string title;
int pageN;
int review;
float price;
};
ostream& operator<<(ostream& os, const Book& book) {
return os << "Title: " << book.title << endl
<< "Pages: " << book.pageN << endl
<< "Review: " << book.review << endl
<< "Price:" << book.price << endl;
}
Then you can output to any stream:
Book book;
ostringstream oss;
oss << book;
To loop over all your books, copying to std::cout
, only when a book has a title, you need std::copy_if
:
bool bookHasTitle(const Book& book) {
return book.title.empty() == false;
}
Book books[10];
copy_if(books, books+10, ostream_iterator<Book>(cout, "\n"),
bookHasTitle);
Upvotes: 22
Reputation: 63471
It's a little hard to tell what's being asked here. You see, it's quite easy to just keep count of how many books you have stored:
int numBooks = 0;
When you add a book, you increment numBooks
up until MAX_BOOKS
.
for( int i=0; i<numBooks; i++ ) ...
If you don't want to do that, you certainly can't test books[i] != '\0'
because that is testing the struct against a single character.
Instead, you might want to test books[i].bookTitle.size() != 0
(or indeed !books[i].bookTitle.empty()
).
for( int i=0; i<MAX_BOOKS && !books[i].bookTitle.empty(); i++ ) ...
Another alternative is to store books in a vector
instead of an array, so you don't have to worry about maximum counts and current counts. The vector can shrink and grow for you.
vector<bookStruct> books;
...
for( int i = 0; i < books.size(); i++ ) ...
Upvotes: 4