Please guide me with this.I have to write a program containing a class called VectorCollection that will be used to store a collection of vectors whose instances are of type string. I get the following error
no match for operator<< in std::cout
when i try to output the vector using cout << (*it) << endl;
I was a bit reluctant to put the full assignment question up on the forum but to avoid confusion here it is. I think i might be totally off track so any guidence will be appriciated.
Write a cpp program containing a class called VectorCollection that will be used to store a collection of vectors whose instances are of type string.
Write a single parameter constructor that receives an array of strings for initializing values in the collection.
Add functions to add instances to the collection, remove instances from the collection, delete all entries from the collection and display the entire collection.
Also overlad the * operator so that it returns the intersection of two VectorCollection objects.
Write a program to test all member functions and overloaded operators in your class.
Next, modify the main function so that instead of creating seperate variables for each Movie object, an array of at least 4 Movie objectsis created with sample data. Loop through the array and output the name, MPAA rating and average rating for each of the four movies.
//movies.h
//******************************************************************************************************
using namespace std;
#ifndef movies_H
#define movies_H
class VectorCollection
{
//member variables
string newtitle,newgentre,newmpaa,newrating;
vector<VectorCollection> movies;
public:
//function declarations
//default constructor
VectorCollection();
//overload constructor
VectorCollection(string,string,string,string);
//destructor
~VectorCollection();
void settitle(string);
void setgentre(string);
void setmpaa(string);
void setrating(string);
void display(vector<VectorCollection>);
};
#endif // MOVIES_H_INCLUDED
//movies.cpp
//******************************************************************************************************
//constructor definition
VectorCollection::VectorCollection()
{
}
//overloaded constructor def
VectorCollection::VectorCollection(string title,string gentre,string mpaa,string rating)
{
newtitle = title;
newgentre = gentre;
newmpaa = mpaa;
newrating = rating;
}
//destructor def
VectorCollection::~VectorCollection()
{
}
//mutator function
void VectorCollection::settitle(string title)
{
newtitle = title;
}
//mutator function
void VectorCollection::setgentre(string gentre)
{
newgentre = gentre;
}
//mutator function
void VectorCollection::setmpaa(string mpaa)
{
newmpaa = mpaa;
}
//mutator function
void VectorCollection::setrating(string rating)
{
newrating = rating;
}
void VectorCollection::display(vector<VectorCollection> movies)
{
vector<VectorCollection>::iterator it;
for ( it = movies.begin(); it < movies.end(); ++it)
{
//copy(movies.begin(),movies.end(),ostream_iterator<string>(cout," "));
cout << (*it) << endl;
}
}
//main.cpp
//******************************************************************************************************
#include <iostream>
#include <string>
#include "movies.h"
using namespace std;
int main()
{
string title,gentre,mpaa,rating;
vector<VectorCollection> movies;
movies.assign(4,VectorCollection());
VectorCollection *a_movie;
VectorCollection list;
for (int i = 0; i < 3; i++)
{
cout << "Enter the title : ";
cin >> title;
cout << "Enter the gentre: ";
cin >> gentre;
cout << "Enter the MPAA: ";
cin >> mpaa;
cout << "Enter the rating: ";
cin >> rating;
a_movie = new VectorCollection;
a_movie ->settitle(title);
a_movie ->setgentre(gentre);
a_movie ->setmpaa(mpaa);
a_movie ->setrating(rating);
movies.push_back(*a_movie);
cin.get();
}
list.display(movies);
return 0;
}
Besides all the other problems already pointed out, you have a std::vector<VectorCollection> in your VectorCollection class.
Standard containers cannot hold incomplete types. If you want to do this, you should have a vector of pointers to VectorCollection or use boost::ptr_vector which is designed specifically to hold pointers to classes.
Boost.Container will also allow you to do what you're trying.
You have a vector of VectorCollections. There is no << ostream operator for your VectorColections object defined. To be able to print contents of your own class using << operator you have to properly implement it for your class.
You may find an answer how to do it here:
How to properly overload the << operator for an ostream?
You need to provide an output stream operator for VectorCollection:
std::ostream& operator<<(std::ostream& os, const VectorCollection& v)
{
return os << "booh!";
}
Related
#include <iostream>
using namespace std;
class car{
string owner;
string car_num;
string issue_date;
car(string o, string cn, string id)
{
owner = o;
car_num = cn;
issue_date = id;
}
void getInfo()
{
cout << "Car's Owner's Name : " << owner << endl;
cout << "Cars' Number : " << car_num << endl;
cout << "Car's Issue Date : " << issue_date << endl;
}
};
int main()
{
int n;
cout << "Enter total number of cars stored in your garage : \n";
cin >> n;
car c1[n]; //incomplete code due to the issue
return 0;
}
Here I want to take the total car numbers from user. And also want to take the car properties from user by using a loop. But how Can I do that while using a constructor?
My advice is not to over use the constructor. It supposed to construct, and really should only construct. In your case, you don't even really need a constructor.
Instead add a new function to do initialization.
Traditional is to use an operator >> which is often an external function.
As for the loop...
car c1[n]; //incomplete code due to the issue
is not legal C++ (although it's allowed in C, and many compilers that are also C compilers)
It's better to use a vector. So...
vector<car> c1(n);
for (auto& c : c1)
cin >> c;
An advanced technique is to use a istream iterator, which will allow you to use algorithms like std::copy, calling the input operator for each member of the vector. However, it's really not required, just a "nicety"
car c1[n]; //incomplete code due to the issue
In fact, you have 2 issues here:
Variable-Length Arrays (VLA) are not allowed in standard C++. They
are optionally allowed in standard C, and are supported by some
C++ compilers as an extension.
You can't have an array of objects w/o default constructor (unless you fully initialize it).
Assuming you don't want to change the class (other than insert public: after the data members), the modern solution should use std::vector:
std::vector<car> c;
//incomplete part
for(int i = 0; i < n; i++){
std::string owner, car_num, issue_date;
//TODO: get the strings from the user here ...
c.emplace_back(owner, car_num, issue_date);
}
Use pointer array instead.e.g.
car* c1[n];
//incomplete part
for(int i = 0; i < n; i++){
//take input and process
c1[i] = new car(//put processed inputs here);
}
PS: I feel like I made a mistake somewhere but can't test it now. If it doesn't work, put a comment here.
You can use loop with std::cin, likefor(int i=0;i<n;++i){std::cin<<num;}. The 'n' I mentioned in the code can also be assigned by std::cin
int n;
std::cin>>n;
car* cars=new car[n];
for(int i=0;i<n;++i)
{
std::getline(cars[i].owner,std::cin);
// and something other you'd like to do, like to test its validity
}
#include <iostream>
using namespace std;
class car{
public:
string owner;
string car_num;
string issue_date;
void cars(string o, string cn, string id)
{
owner = o;
car_num = cn;
issue_date = id;
getInfo();
}
void getInfo()
{
cout << "Car's Owner's Name : " << owner << endl;
cout << "Cars' Number : " << car_num << endl;
cout << "Car's Issue Date : " << issue_date << endl;
}
};
int main()
{
int n;
string a,b,c;
cout << "Enter total number of cars stored in your garage : \n";
cin >> n;
car cas[n]; //incomplete code due to the issue
for(int i=0;i<n;++i)
{
cout<<"value1:";
cin>>a;
cout<<"value2:";
cin>>b;
cout<<"value3:";
cin>>c;
cas[i].cars(a,b,c);
}
return 0;
}
I am trying to write a program to print a vector of object pointers backwards.
My instructions for the part of the lab im stuck on:
Function main() to use the GroceryItem class above
a. Read a grocery
item from standard input (std::cin) until end of file. For each item
read:
i. Store the item in a dynamically allocated object
ii. Store the pointer to the item in a standard vector
b. After you have reached the end of file, write the grocery items to standard output (std::cout) in reverse order.
c. Be sure to release the
dynamically allocated objects before exiting the program
I tried looking at multiple forums and can't figure out how to print my vector forwards or backwards since it is a pointer to an object. I'm confused on how to print each member within the object
#include <iostream>
#include "GroceryItem.hpp"
#include <vector>
#include <string>
int main()
{
// vector of GroceryItem pointer
std::vector<GroceryItem*> groceries;
// variables for the parameter of the constructor
std::string upc;
std::string brand;
std::string product;
double price;
int size;
std::cout << "How many grocery items are in your list: ",
std::cin >> size; // size of vector
for (int i = 0; i < size; i++)
{
std::cout << "UPC: ", std::cin >> upc;
std::cout << "Brand Name: ", std::cin >> brand;
std::cout << "Product Name: ", std::cin >> product;
std::cout << "Price: ", std::cin >> price;
// constructor of GroceryItem object
groceries.push_back(new GroceryItem(upc, brand, product, price));
}
// trying to print the vector backwards but it only prints the
// address (i want it to print each memeber of the object)
int iterator = size - 1;
while (iterator != -1)
{
std::cout << groceries[iterator] << "\n";
iterator--;
}
return 0;
}
//trying to print the vector backwards but it only prints the
//address (i want it to print each memeber of the object)
In that case, use:
std::cout << *(groceries[iterator]) << "\n";
However, to be able use that, you must add the following overload:
std::ostream& operator<<(std::ostream& out, GroceryItem const&);
I'm collecting names and test scores to populate a vector. Both the function and main method can't recognize the struct's members. How can I get it to see the members? Or is there a better way to populate a vector of structs with user input using a function?
I've searched other similar posts, but it seems like it's just a simple code error I missed.
#include <iostream>
#include <vector>
using namespace std;
const int classSize = 1;
struct StudentType {
string studentFName;
string studentLName;
int testScore;
char grade;
};
vector<StudentType> collectStudentData(vector<StudentType> students[classSize]) {
for (int i = 0; i < classSize; i++) {
cout << "Student " << i << "'s name and test score" << endl;
cin >> students[i].studentFName >> students[i].studentLName >> students[i].testScore;
}
return students[classSize];
};
int main() {
vector<StudentType> students[classSize] = {};
students[classSize] = collectStudentData(students);
cout << students[1].studentFName << students[1].studentLName << students[1].studentFName;
};
'studentFName': is not a member of 'std::vector>'
This line creates an array of vectors:
vector<StudentType> students[classSize] = {};
What you want is this a single vector:
vector<StudentType> students;
Where that gets initialized to a zero-length array.
When it comes to adding data you don't need to return from the other method, you can pass in a reference and add to it:
void collectStudentData(vector<StudentType>& students) {
for (int i = 0; i < classSize; i++) {
// Read in one at a time
StudentType student;
cout << "Student " << i << "'s name and test score" << endl;
cin >> student.studentFName >> student.studentLName >> student.testScore;
// Add to the array
students.push_back(student);
}
}
Ideally classSize is either passed in as an argument, or you just type a blank line to end input. Using a global variable is really messy and should be strongly discouraged.
vector<StudentType> students[classSize]
Is one issue. You are not declaring a function that takes a vector, you are declaring a function that takes an array of vectors.
Secondly, if you only applied that change you would be passing an empty vector, you can initialize vector to be a particular size by passing in the size to the constructor.
Furthermore, it seems that you would benefit from passing the students vector by reference
vector<StudentType>& students
instead, the & creates a reference. Right now your code is copying the vector when it is passed into the function
#include <iostream>
#include <vector>
using namespace std;
const int classSize = 1;
struct StudentType {
string studentFName;
string studentLName;
int testScore;
char grade;
};
void collectStudentData(vector<StudentType>& students) {
for (int i = 0; i < classSize; i++) {
cout << "Student " << i << "'s name and test score" << endl;
cin >> students[i].studentFName >> students[i].studentLName >> students[i].testScore;
}
return students;
};
int main() {
vector<StudentType> students{classSize};
collectStudentData(students);
cout << students[0].studentFName << students[0].studentLName << students[0].studentFName;
};
If you wanted to improve the code further, you would use an iterator in the for loop instead, and preferably you wouldn't need to construct the vector in main, and pass it into a function to mutate it. You could just construct it and return it from the function.
I initialized objects in my code using a house number (int) and the person's name (string). This part of my code works and it displays the house number and person correctly.
#include <iostream>
#include <vector>
#include <string>
using namespace std;
//AddressBook class definition
class AddressBook
{
public:
//Declare a constructor that has one parameter for each data member
AddressBook(int, string);
//Declare a set method for house number
void setHouseNum(int);
//Declare a get method for house number
int getHouseNum();
//Declare a set method for name
void setName(string);
//Declare a get method for name
string getName();
void displayAddressBook();
private:
//Declare a int data member for house number
int houseNum;
//Declare a string data member for name
string name;
};
// constructor
AddressBook::AddressBook(int num, string personName)
{
setHouseNum(num);
setName(personName);
}
void AddressBook::setHouseNum(int num)
{
houseNum = num;
}
int AddressBook::getHouseNum()
{
return houseNum;
}
void AddressBook::setName(string personName)
{
name = personName;
}
string AddressBook::getName()
{
return name;
}
void AddressBook::displayAddressBook()
{
cout << getHouseNum() << " " << getName() << endl;
}
int main()
{
AddressBook addressBook(3, "Jim");
addressBook.displayAddressBook();
AddressBook addressBook2(5, "Bob");
addressBook2.displayAddressBook();
AddressBook addressBook3(2, "Jeb");
addressBook3.displayAddressBook();
string command;
cout << "Available Commands Are:" << endl;
cout << "Add, Remove, Sort, Print" << endl;
return 0;
}
Output:
3 Jim
5 Bob
2 Jeb
Available Commands Are:
Add, Remove, Sort, Print
The next part is what I'm having trouble with. I'm supposed to read the user input to see what they want to do and perform the operations listed above. So, if they say Add, and then enter "2 Jeb", the code has to say 2 already exists. If it doesn't exist, it has to add it as an object and print the entire list back out.
I know that you can use getline(cin,name) to get the name from the user but I do not know how to implement that in my code to do what I want it to. Once I get the user input string, how do I create an object with it? Also, how do you read an integer the user inputs into an object because I read that getline works for strings and not integers.
Once I read the integer and string input from the user, how do I check if the house number already exists in my objects? If I can get some help with just these two things I can figure the rest out.
Thank you.
class vehicle{
private:
vector<string>carList;
public:
void info();
void displayCarInfo(vector<string>&carList);
}
void vehicle::info(){
char a;
string choice;
do{
cout<<"Please enter your car Reg number: ";
cin >> carPlate;
carList.push_back(carPlate);
cout << "Do you want to continue add car info(y/n)?";
cin >> choice;
}while(choice == "y");
}
void vehicle::displayCarInfo(vector<string>&carList){
for(int i = 0; i < 100; i++){
cout << carList[i];
}
}
//----------------------------------------------------------------
int main(){
vehicle a;
a.displayCarInfo(carList);
return 0;
}
Questions:
Error show when display all the car list. How to solve it?
And how I can retrieve information for particular element inside carList?
You don't need to pass the vector as an argument to void displayCarInfo();:
class Vehicle{ //<--- define classes starting with uppercase
private:
vector<string>carList;
public:
void info();
void displayCarInfo();
}; //<----- you need a semicolon here
The termination condition should be the vector size.
void vehicle::displayCarInfo(){
for(int i = 0; i < carList.size(); i++){
cout << carList[i];
}
}
The in the main():
int main(){
vehicle a;
a.displayCarInfo();
return 0;
}
If I consider that the and header files were included then too, the program has so many stray compilation errors. Did you not check those ??
Like: choice and carPlate was never declared. Class doesn't end with a ';' etc.
Issues: 1. You create a vehicle 'a' and never put anything in the member variables. I guess the info() function was supposed to do that, then why wasn't it called. I guess you'd need to do that in some loop.
You made the carList vector private and tried to pass the same as an argument from main to the displayCarInfo() func. I hope you realize that such a thing won't be required as being a member function to that same class it can access the carList directly. you simply need to call the public function using an object.
Since Vectors are unbounded (meaning their range can grow and shrink) it's not a good idea to print the content of an vector using a constant loop. That way you always risk a chance of either overrunning the loop or under-running it.
prefer
for vector<string>::iterator it = carList.begin(); it!= carList.end(); it++) std::cout << *it << std::endl;
Although there are smarter ways to do the same using ostream_iterators and std::copy, but that can rest for now.