How to manipulate vector of class type in C++
Hi all,
I built a class type 'books' which includes the title and the price of a particular book. And I want to use vectors to store all the books information I have. This code should be able to get all the books' information and store them into the vector.
But it seems no possible to use xxx.push_back(yyy) or iterators to add new elements to vector<books>.... Could anyone show me the correct way to deal with this kind of problem?
Thanks in advance.
This is the code I used by mistake.
Code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class books{
private:
string title;
double price;
public:
void getname(){
string temp;
cout<<"Please input the name of the book"<<endl;
cin>>temp;
title=temp;
}
void printname(){
cout<<"Title"<<title<<endl;
}
void getprice(){
double temp;
cout<<"Please input the price of the book"<<endl;
cin>>temp;
price=temp;
}
void printprice(){
cout<<"Price"<<price<<endl;
}
};
int main(){
char ch;
vector<books> bvec;
vector<books>::iterator iter=bvec.begin();
do{
*iter.getname();
*iter.getprice();
iter++;
cout<<"Another book info?"<<endl;
cin>>ch;
}while(ch=='y');
cout<<"The Books Stored:"<<endl;
for(iter=bvec.begin();iter!=bvec.end();++iter){
*iter.printname();
*iter.printprice();
}
return 0;
}
Re: How to manipulate vector of class type in C++
Quote:
Originally Posted by
ertss
I built a class type 'books' which includes the title and the price of a particular book.
So why call it books, i.e. not book (singular).
Quote:
Originally Posted by
ertss
Code:
int main(){
char ch;
vector<books> bvec;
vector<books>::iterator iter=bvec.begin();
//...
}
You create an empty vector, so bvec.begin() equals bvec.end(). Dereferencing that iterator gives undefined behavior. Instead, create and initialize an object and use push_back to add it to the vector.
Bye the way, it's not a good idea to put i/o in member functions like that. Better to keep it outside the class.
Re: How to manipulate vector of class type in C++
Thank you Drmmr.
But I still didn't get how to use push_back when you are dealing with a vector of class type.
For example, in my code, the class type has two private members 'price' and 'title'. Obviously we cannot
access them and modify them without calling the the member function.
And with push_back, how could I do that?
Re: How to manipulate vector of class type in C++
First, let me say that, due to operator precedence, this doesn't mean what you think it does and therefore won't compile:
This does:
But because it looks ugly that way and is a really common construct, C++ has the -> operator:
Quote:
Originally Posted by
ertss
And with push_back, how could I do that?
You can't do that at the same time you push_back(). You could do it after the push_back() but that would be unnecessarily complicated. Instead, consider doing it before the push_back(), like this:
Code:
do{
books new_book;
new_book.getname();
new_book.getprice();
bvec.push_back(new_book);
cout<<"Another book info?"<<endl;
cin>>ch;
}while(ch=='y');
Re: How to manipulate vector of class type in C++
Thank you Eri523! That helps a lot!
But I met another problem with my code using getline(cin,temp);
I changed my code to this. The thing is, the first time in the do...while loop, everything is good.
But after i input 'y' to execute another do...while loop, it just skip the new_book.getname() part.
I believe it's something wrong with the getline usage. Because if i changed it to cin>>temp, it works just
fine.
Code:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class books{
private:
string title;
double price;
public:
void getname(){
string temp;
cout<<"Please input the name of the book"<<endl;
getline(cin,temp);
title=temp;
}
void printname(){
cout<<"Title:"<<title<<endl;
}
void getprice(){
double temp;
cout<<"Please input the price of the book"<<endl;
cin>>temp;
price=temp;
}
void printprice(){
cout<<"Price:"<<price<<endl;
}
};
int main(){
char ch;
vector<books> bvec;
vector<books>::iterator iter=bvec.begin();
do{
books new_book;
new_book.getname();
new_book.getprice();
bvec.push_back(new_book);
//iter->getname();
//iter->getprice();
//iter++;
cout<<"Another book info?"<<endl;
cin>>ch;
}while(ch=='y');
cout<<"The Books Stored:"<<endl;
for(iter=bvec.begin();iter!=bvec.end();++iter){
iter->printname();
iter->printprice();
}
return 0;
}
Re: How to manipulate vector of class type in C++
Quote:
Originally Posted by
ertss
But I met another problem with my code using getline(cin,temp);
I changed my code to this. The thing is, the first time in the do...while loop, everything is good.
But after i input 'y' to execute another do...while loop, it just skip the new_book.getname() part.
I believe it's something wrong with the getline usage. Because if i changed it to cin>>temp, it works just
fine.
The problem is that after you read the price using >> the endline following the price remains in the input stream. Next time you call getline, it will read an emtpy line (i.e. only the endline character). The easiest way to avoid this is to use getline all the time, then use a stringstream to parse the input.
Code:
#include <iostream>
#include <sstream>
int main()
{
std::string name;
std::getline(std::cin, name);
int price;
std::string line;
std::getline(std::cin, line);
std::istringstream iss(line);
iss >> price;
}
Also see http://www.parashift.com/c++-faq-lite/input-output.html
Re: How to manipulate vector of class type in C++
Quote:
Originally Posted by
D_Drmmr
The problem is that after you read the price using >> the endline following the price remains in the input stream. Next time you call getline, it will read an emtpy line (i.e. only the endline character). The easiest way to avoid this is to use getline all the time, then use a stringstream to parse the input.
Code:
#include <iostream>
#include <sstream>
int main()
{
std::string name;
std::getline(std::cin, name);
int price;
std::string line;
std::getline(std::cin, line);
std::istringstream iss(line);
iss >> price;
}
Also see
http://www.parashift.com/c++-faq-lite/input-output.html
Or you can just add cin.ignore() before getline. ignore() function (as its name says) ignore any previous input so you will be able to enter book name.