convert function into member function? - c++

I'm new here and I'm looking for help with a program written in c++.
I want to convert following functions that are not in a class nor in main() of my program
void PrintInventory(vector<Item*> inventory);
vector<Item*> AddItemToInventory(vector<Item*> inventory);
vector<Item*> UpdateItemQtyInInventory(vector<Item*> inventory);
vector<Item*> RemoveItemFromInventory(vector<Item*> inventory);
into public function members of a class Inventory that have no parameters and return nothing.
I've been working on that for 4 days now and just can't figure out how I'm supposed to change these functions to be void and have no parameter without destroying the whole program...
If I go exactly by what the instruction say which is to make a void/no parameters out of the four functions, I would get something like:
class Inventory
{
public:
void PrintInventory() {}
void AddItemToInventory() {}
void UpdateItemQtyInInventory() {}
void RemoveItemFromInventory() {}
private:
vector<Item*> inventory;
};
Please give me a hint. I feel like the solution must be simple but I've been completely stuck for days.
Thanks for your help.
EDIT:
I'm still getting a bunch of errors and think I need to say a bit more about my code:
I have a base class Item and two derived classes Produce and Book. Then I have four function calls:
// Print all items in the inventory
void PrintInventory(vector<Item*> inventory);
// Dialogue to create a new item, then add that item to the inventory
vector<Item*> AddItemToInventory(vector<Item*> inventory);
// Dialogue to update the quantity of an item, then update that item in the inventory
vector<Item*> UpdateItemQtyInInventory(vector<Item*> inventory);
// Dialogue to remove a specific item, then remove that specific item from the inventory
vector<Item*> RemoveItemFromInventory(vector<Item*> inventory);
Next comes the main and my class Inventory that now has four converted functions with no return and no parameters that were not originally inside the class Inventory and had parameters/return before.
Here is the whole code, I think it's better to understand this way:
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
#include <cstring>
using namespace std;
class Item {
public:
void SetName(string nm)
{
name = nm;
};
void SetQuantity(int qnty)
{
quantity = qnty;
};
void SetPrice(int prcInDllrs) //step1
{
priceInDollars = prcInDllrs; //step1
};
virtual void Print()
{
cout << name << " " << quantity << endl;
};
virtual ~Item()
{
return;
};
protected:
string name;
int quantity;
int priceInDollars; //step1
};
class Produce : public Item { // Derived from Item class
public:
void SetExpiration(string expir)
{
expiration = expir;
};
void Print()
{
cout << name << " x" << quantity
<< " for $" << priceInDollars //step1
<< " (Expires: " << expiration << ")"
<< endl;
};
private:
string expiration;
};
//step 2 add derived class Book
class Book : public Item { // Derived from Item class
public:
void SetAuthor(string authr) //create author function with parameter
{
author = authr;
};
void Print()
{
cout << name << " x" << quantity
<< " for $" << priceInDollars //step1
<< " (Author: " << author << ")"
<< endl;
};
private:
string author;
};
// Print all items in the inventory
void PrintInventory(vector<Item*> inventory);
// Dialogue to create a new item, then add that item to the inventory
vector<Item*> AddItemToInventory(vector<Item*> inventory);
// Dialogue to update the quantity of an item, then update that item in the inventory
vector<Item*> UpdateItemQtyInInventory(vector<Item*> inventory);
// Dialogue to remove a specific item, then remove that specific item from the inventory
vector<Item*> RemoveItemFromInventory(vector<Item*> inventory);
int main() {
vector<Item*> inventory;
string usrInptOptn = "default";
while (true) {
// Get user choice
cout << "\nEnter (p)rint, (a)dd, (u)pdate, (r)emove, or (q)uit: ";
getline(cin, usrInptOptn);
// Process user choice
if (usrInptOptn.size() == 0) {
continue;
}
else if (usrInptOptn.at(0) == 'p') {
PrintInventory(inventory);
}
else if (usrInptOptn.at(0) == 'a') {
inventory = AddItemToInventory(inventory);
}
else if (usrInptOptn.at(0) == 'u') {
inventory = UpdateItemQtyInInventory(inventory);
}
else if (usrInptOptn.at(0) == 'r') {
inventory = RemoveItemFromInventory(inventory);
}
else if (usrInptOptn.at(0) == 'q') {
cout << "\nGood bye." << endl;
break;
}
}
return 0;
}
class Inventory {
public:
void PrintInventory() {
unsigned int i = 0;
if (inventory.size() == 0) {
cout << "No items to print." << endl;
}
else {
for (i = 0; i<inventory.size(); ++i) {
cout << i << " - ";
inventory.at(i)->Print();
}
};
}
void AddItemToInventory() {
Produce* prdc;
Book* book; //create new pointer object of class book
string usrInptName = "";
string usrInptQntyStr = "";
istringstream inSS;
int usrInptQnty = 0;
string usrInptExpr = "";
int usrInptPrc = 0; //step1
string usrInptAuthr = ""; //declare variable
string usrInptBookName = "";
int usrInptQntyBook = 0;
string usrInptQntyBookStr = "";
string usrInptChoice = " ";
//loop user choice and ask again if choice is not valid
do {
cout << "Enter choice of adding (b)ook or (p)roduce: ";
getline(cin, usrInptChoice);
if (usrInptChoice != "b" && usrInptChoice != "p") {
cout << "Invalid Choice" << endl;
}
} while (usrInptChoice != "b" && usrInptChoice != "p");
//only ask for inventory type accoring to user input p or b
if (usrInptChoice == "p") {
cout << "Enter name of new produce: ";
getline(cin, usrInptName);
cout << "Enter quantity: ";
getline(cin, usrInptQntyStr);
inSS.str(usrInptQntyStr);
inSS >> usrInptQnty;
inSS.clear();
cout << "Enter expiration date: ";
getline(cin, usrInptExpr);
cout << "Enter the price per item : $"; //step1
cin >> usrInptPrc; //step1
prdc = new Produce;
prdc->SetName(usrInptName);
prdc->SetQuantity(usrInptQnty);
prdc->SetExpiration(usrInptExpr);
prdc->SetPrice(usrInptPrc);
inventory.push_back(prdc);
}
if (usrInptChoice == "b") {
cout << "Enter name of new book: ";
getline(cin, usrInptBookName);
cout << "Enter quantity: ";
getline(cin, usrInptQntyBookStr);
inSS.str(usrInptQntyBookStr);
inSS >> usrInptQntyBook;
inSS.clear();
cout << "Enter author: ";
getline(cin, usrInptAuthr);
cout << "Enter the price per item : $"; //step1
cin >> usrInptPrc; //step1
book = new Book;
book->SetName(usrInptBookName);
book->SetQuantity(usrInptQntyBook);
book->SetAuthor(usrInptAuthr);
book->SetPrice(usrInptPrc);
inventory.push_back(book);
};
}
void UpdateItemQtyInInventory() {
string usrIndexChoiceStr = "";
unsigned int usrIndexChoice = 0;
istringstream inSS;
string usrInptQntyStr = "";
int usrInptQnty = 0;
if (inventory.size() == 0) {
cout << "No items to update." << endl;
}
else {
PrintInventory();
do {
cout << "Update which item #: ";
getline(cin, usrIndexChoiceStr);
inSS.str(usrIndexChoiceStr);
inSS >> usrIndexChoice;
inSS.clear();
} while (!(usrIndexChoice < inventory.size()));
cout << "Enter new quantity: ";
getline(cin, usrInptQntyStr);
inSS.str(usrInptQntyStr);
inSS >> usrInptQnty;
inSS.clear();
inventory.at(usrIndexChoice)->SetQuantity(usrInptQnty);
};
}
void RemoveItemFromInventory() {
istringstream inSS;
string usrIndexChoiceStr = "";
unsigned int usrIndexChoice = 0;
string usrInptQntyStr = "";
if (inventory.size() == 0) {
cout << "No items to remove." << endl;
}
else {
PrintInventory();
do {
cout << "Remove which item #: ";
getline(cin, usrIndexChoiceStr);
inSS.str(usrIndexChoiceStr);
inSS >> usrIndexChoice;
inSS.clear();
} while (!(usrIndexChoice < inventory.size()));
inventory.erase(inventory.begin() + usrIndexChoice);
};
}
private:
vector<Item*> inventory;
};
I don't get any compilation errors in Visual Studio but when I try to build, there are 5 errors. Compiling the program in Geany gives me no errors either but when I build, it says:
undefined reference to `PrintInventory(std::vector<Item*, std::allocator<Item*> >)'
undefined reference to `AddItemToInventory(std::vector<Item*, std::allocator<Item*> >)'
undefined reference to `UpdateItemQtyInInventory(std::vector<Item*, std::allocator<Item*> >)'
undefined reference to `RemoveItemFromInventory(std::vector<Item*, std::allocator<Item*> >)'
collect2.exe: error: ld returned 1 exit status
Compilation failed.
I feel like I'm missing some basic, simple thing but I just can't figure it out. The instruction is confusing to me when it says I have to convert the functions PrintInventory, AddItemToInventory, UpdateItemQtyInInventory,
and RemoveItemFromInventory into void/no parameters but which functions does it refer to? The four definition lines? The actual functions? Both? And what about the main and the other classes? Wouldn't I need to change things there as well?

I believe your code conversion is correct. Since 'Inventory vector' is a a member variable it can be accessed by all the other member function and can also be manipulated. This removes the requirement for passing vector as argument.
Now for returning the vector I would suggest adding a new "GetInventory()" method which returns the vector or take a reference to pass the vector.
Hope it helps.

Thanks to WhozCraig, my problem has been solved:
"The class definition of Inventory has to come before main() somehow. Move it above main() and it should work."

Basic testing:
Note, there are no pointers in here
void test()
{
class T_item
{
public:
string name;
int quantity;
int priceInDollars;
};
vector<T_item> inventory;
T_item temp;
//add item:
temp.name = "name1";
temp.quantity = 1;
temp.priceInDollars = 1;
inventory.push_back(temp);
temp.name = "name2";
temp.quantity = 2;
temp.priceInDollars = 2;
inventory.push_back(temp);
cout << "print:\n";
for each(T_item item in inventory)
{
cout << item.name << endl;
cout << item.quantity << endl;
cout << item.priceInDollars << endl << endl;
}
//modify item at index 1:
inventory[1].name = "modified";
//delete item at index 0:
inventory.erase(inventory.begin() + 0);
cout << "print again:\n";
for each(T_item item in inventory)
{
cout << item.name << endl;
cout << item.quantity << endl;
cout << item.priceInDollars << endl << endl;
}
}
int main()
{
test();
return 0;
}

Related

MultiMap not Printing List

I am having 2 issues with my code.
The 1st issue is that my multimap is not printing, and I don't know why.
The 2nd issue is that I don't know how to create a function to search and find a specific item in my multimap.
You can change as much of the code as you want, but I need to keep the class or change it to a struct.
#include<iostream>
#include<string>
#include<iterator>
#include<map>
#include<algorithm>
#include<iomanip>
using namespace std;
class SongNode {
public:
string title;
string artist;
float rating;
};
//Constants
#define INFINITE_LOOP 1
#define LEFT_JUSTIFIED 30
//Prototypes
void sortByArtist(multimap<string, SongNode>& newSongNode);
void sortByRating(multimap<string, SongNode>& newSongNode);
//FUNCTION : void sortByArtist
//PARAMETER : multimap<string, SongNode>&newSongNode
//RETURN : void
//DESCRIPTION : This function will sort the multimap by the artist of the song
void sortByArtist(multimap<string, SongNode>&newSongNode) {
multimap<string, SongNode>temp;
for (auto i = newSongNode.begin(); i != newSongNode.end(); i++)
temp.insert(pair<string, SongNode>(i->second.artist, i->second));
newSongNode.clear();
for (auto i = temp.begin(); i != temp.end(); i++)
newSongNode.insert(pair<string, SongNode>(i->second.artist, i->second));
temp.clear();
}
//FUNCTION : void sortByRating
//PARAMETER : (multimap<string, SongNode>& newSongNode
//RETURN : void
//DESCRIPTION : This function will sort the multimap by the rating.
void sortByRating(multimap<string, SongNode>& newSongNode) {
multimap<float, SongNode, greater<int>> temp;
for (auto i = newSongNode.begin(); i != newSongNode.end(); i++)
temp.insert(pair<int, SongNode>(i->second.rating, i->second));
newSongNode.clear();
for (auto i = temp.begin(); i != temp.end(); i++)
newSongNode.insert(pair<string, SongNode>(" ", i->second));
temp.clear();
}
int main() {
multimap<string, SongNode> songList;
multimap<string, SongNode>::iterator itr;
string title;
string artist;
int rating;
SongNode* newSongNode = new SongNode;
cout << "Please enter a title artist and rating\n";
while (INFINITE_LOOP) {
cout << "Title: ";
cin >> title;
if (title == ".") {
break;
}
cout << "Artist: ";
cin >> artist;
cout << "Rating: ";
cin >> rating;
//Error check for rating
while (INFINITE_LOOP) {
if (rating < 1) {
cout << "The rating you have entered is less then 1\n";
cout << "Rating: ";
cin >> rating;
break;
}
else if (rating > 5) {
cout << "The rating you have to enterd is greater then 5\n";
cout << "Rating: ";
cin >> rating;
break;
}
else
break;
}
SongNode* newNode = new SongNode;
newNode->title = title;
newNode->artist = artist;
newNode->rating = rating;
songList.insert(pair<string, SongNode>(title, *newSongNode));
}
//display the two lists here.
cout << "Artist Sorted List\n";
sortByArtist(songList);
for (itr = songList.begin(); itr != songList.end(); ++itr) {
cout << "Title" << left << setw(LEFT_JUSTIFIED) << itr->second.title;
cout << "Artist" << left << setw(LEFT_JUSTIFIED) << itr->second.artist;
cout << "Rating" << left << setw(LEFT_JUSTIFIED) << itr->second.rating<<endl;
}
cout << "\n";
cout << "Rating Sorted List\n";
sortByRating(songList);
delete newSongNode;
return 0;
}
First of all, you have two variables with similar names, and you definitely misuse them:
SongNode* newSongNode = new SongNode;
// ...
SongNode* newNode = new SongNode;
newNode->title = title;
newNode->artist = artist;
newNode->rating = rating;
songList.insert(pair<string, SongNode>(title, *newSongNode));
You are initializing the newNode but inserting the newSongNode. The values are initialized with empty strings, so that may explain no printing.
As for "searching in a multimap" be more specific in what your problem is.
You are not populating the songList with the SongNode objects that you fill with data. You have an extra SongNode that has no data in it, which is the only object you are putting into the songList. So there is nothing to print.
Try this instead:
#include <iostream>
#include <string>
#include <iterator>
#include <map>
#include <algorithm>
#include <iomanip>
#include <limits>
using namespace std;
struct SongNode {
string title;
string artist;
float rating;
};
//Constants
#define INFINITE_LOOP 1
#define LEFT_JUSTIFIED 30
//Prototypes
void sortByArtist(multimap<string, SongNode>& newSongNode);
void sortByRating(multimap<string, SongNode>& newSongNode);
//FUNCTION : void sortByArtist
//PARAMETER : multimap<string, SongNode>&newSongNode
//RETURN : void
//DESCRIPTION : This function will sort the multimap by the artist of the song
void sortByArtist(multimap<string, SongNode> &newSongNode) {
multimap<string, SongNode> temp;
for (auto &elem : newSongNode)
temp.insert(make_pair(elem.second.artist, elem.second));
newSongNode.clear();
for (auto &elem : temp)
newSongNode.insert(make_pair(elem.second.artist, elem.second));
}
//FUNCTION : void sortByRating
//PARAMETER : (multimap<string, SongNode>& newSongNode
//RETURN : void
//DESCRIPTION : This function will sort the multimap by the rating.
void sortByRating(multimap<string, SongNode>& newSongNode) {
multimap<float, SongNode, greater<int>> temp;
for (auto &elem : newSongNode)
temp.insert(make_pair(elem.second.rating, elem.second));
newSongNode.clear();
for (auto &elem : temp)
newSongNode.insert(make_pair(" ", elem.second));
}
int main() {
multimap<string, SongNode> songList;
string title, artist;
float rating;
cout << "Please enter a title artist and rating\n";
while (INFINITE_LOOP) {
cout << "Title: ";
cin >> title;
if (title == ".") {
break;
}
cout << "Artist: ";
cin >> artist;
cout << "Rating: ";
cin >> rating;
//Error check for rating
while (INFINITE_LOOP) {
if (!cin) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "The rating you have entered is invalid\n";
}
else if (rating < 1.0f) {
cout << "The rating you have entered is less then 1\n";
}
else if (rating > 5.0f) {
cout << "The rating you have to entered is greater then 5\n";
}
else
break;
cout << "Rating: ";
cin >> rating;
}
SongNode newNode;
newNode.title = title;
newNode.artist = artist;
newNode.rating = rating;
songList.insert(make_pair(title, newNode));
}
//display the two lists here.
cout << "Artist Sorted List\n";
sortByArtist(songList);
for (auto &elem : songList) {
cout << "Title" << left << setw(LEFT_JUSTIFIED) << elem.second.title;
cout << "Artist" << left << setw(LEFT_JUSTIFIED) << elem.second.artist;
cout << "Rating" << left << setw(LEFT_JUSTIFIED) << elem.second.rating << endl;
}
cout << "\n";
cout << "Rating Sorted List\n";
sortByRating(songList);
for (auto &elem : songList) {
cout << "Title" << left << setw(LEFT_JUSTIFIED) << elem.second.title;
cout << "Artist" << left << setw(LEFT_JUSTIFIED) << elem.second.artist;
cout << "Rating" << left << setw(LEFT_JUSTIFIED) << elem.second.rating << endl;
}
cout << "\n";
return 0;
}

My function don't take over the variable value from other function

I have a program to create a phone book in a file. Some of my functions don't work or don't work properly.
user.h
#pragma once
#include <string>
#include <vector>
using namespace std;
class User
{private:
string firstname, lastname, country, city, street;
string phone;
public:
string prefix;
void ReadAllUsers(User[], int&);
void SaveUser(User, int&);
void SaveToFile(const User[], int);
void AddName(User[], int&);
void ListAllUsers(const User[], int&);
void Prefix(User, int);
void ChangePhone(User[], int&);
void Help();
void DeleteUser(User[], int&);
bool Search(string x)
{
return (phone.find(x) != string::npos);
}
};
user.cpp
#include "User.h"
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#pragma warning(disable:4996)
using namespace std;
const string PHONEBOOK_FILENAME = "phonebook.txt";
void User::Help()
{cout<<"\nWELCOME TO THE APPLICATION!\n";
cout<<"Press 0 to display on the screen all records that are saved in the file(phonebook.txt)\n";
cout<<"Press 1 to add 1 or more new record(s) in file(phonebook.txt)\n";
cout<<"Press 2 to delete permanently a record from file(phonebook.txt)\n";
cout<<"Press 3 to sort users from file(phonebook.txt) by name and display them on the screen\n";
cout<<"Press 4 to edit a user phone number and save it after in file(phonebook.txt)\n";
cout<<"Press 5 for help\n";
cout<<"Press 6 to exit the application\n";
}
void User::ReadAllUsers(User people[], int &num_people)
{
ifstream f;
f.open(PHONEBOOK_FILENAME.c_str());
if (f.fail())
{
cout << "Unable to open file " << endl;
return ;
}
int i = 0;
while (!f.eof() && i < 100)
{ getline(f, people[i].firstname);
getline(f, people[i].lastname);
getline(f, people[i].phone);
getline(f, people[i].country);
getline(f, people[i].city);
getline(f, people[i].street);
i++;
}
num_people = i;
f.close();
}
//Add country prefix to the phone number
void User::Prefix(User person, int num_people)
{string filecountry;
ifstream f;
f.open("prefix.txt");
{
while (getline(f, filecountry))
{
if (person.country == filecountry )
{
f.ignore();//next line
f >> person.prefix;
}
}
f.close();
}
}
void User::SaveUser(User person, int &num_people)
{
ofstream f(PHONEBOOK_FILENAME.c_str(), ios::app ) ;
if (f.fail())
cout << "Unable to open file " << endl;
else
f << person.firstname << " " << person.lastname << " " << person.country << " " << person.city << " " << person.street << " " << person.prefix << "-" << person.phone << endl;
cout << "\nThe user was added\n";
}
//Save data after a modification or after a user delete
void User::SaveToFile(const User people[], int num_people)
{ofstream f;
f.open(PHONEBOOK_FILENAME.c_str());
for(int i = 0; i < num_people; i++)
{
f << people[i].firstname << " " << people[i].lastname << " " << people[i].country << " " << people[i].city << " " << people[i].street << " " << people[i].prefix << " " << people[i].phone << endl;
}
}
// Read user data from the keyboard, add a new contact to the array
void User::AddName(User people[],int &num_people)
{User person;
cout <<"Enter the user's first name: ";
cin >> person.firstname;
cout <<"Enter the user's last name: ";
cin >> person.lastname;
cout <<"Enter the user's country: ";
cin >> person.country;
cout <<"Enter the user's city: ";
cin >> person.city;
cout <<"Enter the user's street: ";
cin >> person.street;
cout <<"Enter the user's phone number: ";
cin >> person.phone;
Prefix(person, num_people);
cout <<"The prefix is " << person.prefix;
for(int i = 0; i < num_people; i++)
{
if( i + 1 == num_people)
people[num_people] = person;
}
SaveUser(person, num_people);
num_people++;
}
// Ask the for person's name to change, find the person in the array and
// change it to the new phone number. Then save the new data to file by
// calling SaveToFile.
void User::ChangePhone(User people[], int &num_people)
{
User person;
int count;
cout <<"Enter name to change: ";
cin >> person.firstname;
for(count = 0; count < num_people; count++)
{
if(people[count].Search(person.firstname))
{ cout <<endl<< people[count].firstname<<endl;
cout <<"Current number"<<people[count].phone;
cout << "\nNew number: ";
cin >> people[count].phone;
SaveToFile(people,num_people);
cout <<"\n\nNew number Saved.";
return;
}
}
if(count = num_people)
cout <<"\nName not found.\n";
}
void User::DeleteUser(User people[], int &num_people)
{string phone;
int count = 0;
ifstream f;
f.open("phonebook.txt");
cout << "Input the phone of user that you want to delete ";
cin >> phone;
for(count = 0; count < num_people; count++)
{
if(people[count].Search(phone))
{ cout <<endl<< people[count].phone<<endl;
people[count].firstname = people[count].lastname = people[count].phone = people[count].country = people[count].city = people[count].street = " ";
}
SaveToFile(people,num_people);
cout <<"\n\nUser deleted.";
return;}
f.close();
}
The function Prefix()(this is to add automatically a country prefix for phone number, this is read from a file) is working but the value of person.prefix it's not taken by SaveUser(), so the value is not wrote in file.The function SaveToFile() save all users on single line in file.
And functions ChangePhone() and DeleteUser don't working.
The problem is that void User::Prefix(User person, int num_people) takes person by value, so it makes a copy of the person, changes the copy, then the copy goes away when the function ends. The original was never changed.
Instead, you want:
void User::Prefix(User & person, int num_people)
To have a reference to the person specified, which will be affected by the changes you make inside the function.
Also, I recommend you change your saveuser to be:
void User::SaveUser(User const & person, int &num_people) const
just to avoid making extra copies of the User object, but it's not incorrect the way you currently have it, I don't think.

vector pointers and retrieving data

I'm a beginner at coding in C++ and every other language. The problem I'm having here is in main() with the first (else if) where (UserInput == sell). I would like the function to print the data stored in the object #listPos to retrieve the cost and input it into my incomplete Profit() function, but every time I dereference the pointer (Search) I get an error code. There's something I'm missing big time please help!!
Ive already tried (*search) but there's a huge error code.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class UnSold{
public:
UnSold(string NameOfShoe, int PurchasePrice ){
name = NameOfShoe;
cost = PurchasePrice;
return;
}
void SetName(string NameOfShoe){
name = NameOfShoe;
return;
}
void SetCost(int PurchasePrice){
cost = PurchasePrice;
return;
}
string GetName() const {
return name;
}
int GetCost() const{
return cost;
}
void Profit();
void PrintItem();
private:
string name;
int cost;
};
void UnSold::Profit(){
static int profit = 0;
//profit += (sold-cost);
}
void UnSold::PrintItem(){
cout << "Name: " << this->name << " Cost: " << this->cost << endl;
}
void PrintEverything(vector<UnSold*> AllItems) {
unsigned int i;
for (i=0; i<AllItems.size(); ++i) {
cout<< i+1 << " ";
(*AllItems.at(i)).PrintItem();
}
}
int main(){
vector<UnSold*> Inventory;
string Name;
int Cost;
string UserInput;
unsigned int listPos;
UnSold* newItem = nullptr;
UnSold* search = nullptr;
while ( UserInput != "quit") {
cout << "Do you want to add, sell, print or quit?" <<endl;
cin >> UserInput;
if ( UserInput == "add") {
cout << "Enter item name: "<<endl;
cin >> Name;
cout << "Enter item cost: " << endl;
cin >> Cost;
newItem = new UnSold(Name, Cost);
Inventory.push_back(newItem);
}
else if ( UserInput == "sell") {
cout << "List Positon: ";
cin >> listPos;
if ( listPos < Inventory.size()){
cout << " Item Sold and Removed from list position " << listPos <<endl;
search = Inventory.at(listPos-1);
//cout<< "contents of Search: "<< search << endl;
delete search;
Inventory.erase(Inventory.begin() + (listPos -1));
}
else{
cout << "Error"<<endl;
}
}
else if ( UserInput == "print") {
PrintEverything(Inventory);
}
else if ( UserInput != "quit"){
}
}
return 0;
}
This is a compile error.
Remove line 85: newItem.at(listPos - 1); and it runs just fine in visual studio.
The issue is that newItem is a pointer to an element. I assume you meant to use Inventory here instead. However, that logic was already done on the previous line.
On a side note, I stongly advise against storing owning pointers like this. There's no good reason in this case not to just use vector<UnSold> instead.
else if ( UserInput == "sell") {
cout << "List Positon: ";
cin >> listPos;
if ( listPos < Inventory.size()){
cout << " Item Sold and Removed from list position " << listPos <<endl;
search = Inventory.at(listPos-1);
//cout<< "contents of Search: "<< search << endl;
delete search;
Inventory.erase(Inventory.begin() + (listPos -1));
Here you mix the use of listPos and listPos - 1.
If you're allowing the user to input position 0 indexed, then
Inventory.at(listPos-1) should be Inventory.at(listPos) and
Inventory.erase(Inventory.begin() + (listPos -1)) should be Inventory.erase(Inventory.begin() + (listPos)).
If you're letting them input the position with the indexing starting at 1, then
if (listPos < Inventory.size()) should be
if(listPos <= Inventory.size() && listPos > 0)

C++ class vector issues

Ok, I'm working on this inventory program, in which what is supposed to happen is the user inputs various bits of information about a particular product, then it gets passed to the inventory, while giving the user the opportunity to change stuff (as you should see in the code). Since I'm doing this for a school project, I have to have the various classes that are there (hence why I haven't gotten rid of them.
Now my issue is with the vectors in class Inventory.
Error 'std::vector> AddProduceToInventory(std::vector<_Ty,std::allocator<_Ty>>)': cannot convert argument 1 from 'std::vector>' to 'std::vector>'
This issue applies to each of those vectors in the class. I only copied one of the identical errors.
I can't figure out what else I'm supposed to do. Here is my code (sorry for the length!)
#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
class Item {
public:
void SetPrice(int prcInDllrs) {
priceInDollars = prcInDllrs; // Somehow I need to keep adding each of these totals to make a grand total price.
}
void SetItemPrice(int whatever) {
itemsPrice = whatever;
}
void SetName(string nm)
{
name = nm;
};
void SetQuantity(int qnty)
{
quantity = qnty;
};
virtual void Print() //Here is my print problem
{
};
virtual ~Item()
{
return;
};
protected:
string name;
int quantity = 0;
int priceInDollars = 0;
int itemsPrice = 0;
};
class Produce : public Item { // Derived from Item class
public:
void SetExpiration(string expir)
{
expiration = expir;
};
void Print()
{
cout << name << " x" << quantity
<< " (Expires: " << expiration << ")" << " for $" << itemsPrice //FILL THIS IN!!!
<< endl;
};
private:
string expiration;
};
class Book : public Item {
public:
void SetAuthor(string athr) {
author = athr;
}
void Print()
{
cout << name << " x" << quantity
<< " for $" << itemsPrice << " (Author: " << author << ")" << endl;
}
private:
string author;
};
class Inventory {
public:
void PrintInventory()
{
if (inventory.size() == 0) {
cout << "No items to print." << endl;
}
else {
for (unsigned int i = 0; i < inventory.size(); ++i) {
cout << i << " - ";
inventory.at(i)->Print();
}
}
cout << "Total inventory value: $" << totalInvPriceInDollars << endl;
}
//I am leaving these out of the equation until I get the PrintInventory working
void AddItemToInventory()
{
vector<Inventory*> AddProduceToInventory(vector<Inventory*> Invntry);
AddProduceToInventory(vector<Inventory*> inventory)
{
Produce* prdc;
string usrInptName = "";
string usrInptQntyStr = "";
istringstream inSS;
int usrInptQnty = 0;
string usrInptExpr = "";
string usrInptPrcStr = "";
int usrInptPrc = 0;
int itemsTotalPrice = 0;
istringstream inDD;
string runningTotal = "";
int sum = 0;
cout << "Enter name of new produce: ";
getline(cin, usrInptName);
cout << "Enter quantity: ";
getline(cin, usrInptQntyStr);
inSS.str(usrInptQntyStr);
inSS >> usrInptQnty;
inSS.clear();
cout << "Enter expiration date: ";
getline(cin, usrInptExpr);
cout << "Enter the price per item: $";
getline(cin, usrInptPrcStr);
inDD.str(usrInptPrcStr);
inDD >> usrInptPrc;
inDD.clear();
itemsTotalPrice = usrInptPrc * usrInptQnty;
prdc = new Produce;
prdc->SetName(usrInptName);
prdc->SetQuantity(usrInptQnty);
prdc->SetExpiration(usrInptExpr);
prdc->SetPrice(usrInptPrc);
prdc->SetItemPrice(usrInptPrc);
inventory.push_back(prdc);
Inventory set;
set.SetInventory(inventory);
return inventory;
}
}
void AddBookToInventory()
{
vector<Inventory*> AddBookToInventory(vector<Inventory*> inventory) {
Book* prdct;
string usrInptName = "";
string usrInptQntyStr = "";
istringstream inSS;
int usrInptQnty = 0;
string usrInptAthr = "";
string usrInptPrcStr = "";
int usrInptPrc = 0;
int itemsTotalPrice = 0;
istringstream inDD;
string runningTotal = "";
int sum = 0;
cout << "Enter name of new book: ";
getline(cin, usrInptName);
cout << "Enter quantity: ";
getline(cin, usrInptQntyStr);
inSS.str(usrInptQntyStr);
inSS >> usrInptQnty;
inSS.clear();
cout << "Enter author: ";
getline(cin, usrInptAthr);
cout << "Enter the price per item: $";
getline(cin, usrInptPrcStr);
inDD.str(usrInptPrcStr);
inDD >> usrInptPrc;
inDD.clear();
prdct = new Book;
prdct->SetName(usrInptName);
prdct->SetQuantity(usrInptQnty);
prdct->SetPrice(usrInptPrc);
prdct->SetAuthor(usrInptAthr);
prdct->SetItemPrice(usrInptPrc);
inventory.push_back(prdct);
Inventory set;
set.SetInventory(inventory);
return inventory;
}
}
void UpdateItemQtyInventory()
{
//This is the update function in which we can change how many items a certain purchase has
vector<Item*> UpdateItemQtyInInventory(vector<Item*> inventory) {
string usrIndexChoiceStr = "";
unsigned int usrIndexChoice = 0;
istringstream inSS;
string usrInpuQntyStr = "";
int usrInptQnty = 0;
if (inventory.size() == 0) {
cout << "No items to update." << endl;
}
else {
PrintInventory(inventory);
do {
cout << "Update which item #: ";
getline(cin, usrIndexChoiceStr);
inSS.str(usrIndexChoiceStr);
inSS >> usrIndexChoice;
inSS.clear();
} while (!(usrIndexChoice < inventory.size()));
cout << "Enter new quantity: ";
std::getline(cin, usrInptQntyStr);
inSS.str(usrInptQntyStr);
inSS >> usrInptQnty;
inSS.clear();
inventory.at(usrIndexChoice)->SetQuantity(usrInptQnty);
}
return inventory;
}
}
void RemoveItemFromInventory()
{
//Here we will be removing an entire item from the inventory
vector<Item*> RemoveItemFromInventory(vector<Item*> inventory) {
istringstream inSS;
string usrIndexChoiceStr = "";
unsigned int usrIndexChoice = 0;
string usrInptQntyStr = "";
if (inventory.size() == 0) {
cout << "No items to remove." << endl;
}
else {
PrintInventory(inventory);
do {
cout << "Remove which item #: ";
getline(cin, usrIndexChoiceStr);
inSS.str(usrIndexChoiceStr);
inSS >> usrIndexChoice;
inSS.clear();
} while (!(usrIndexChoice < inventory.size()));
inventory.erase(inventory.begin() + usrIndexChoice);
}
return inventory;
}
}
void GetTotalValueAsPrice()
{
}
void SetInventory(vector<Item*> invntry) {
inventory = invntry;
}
private:
int totalInvPriceInDollars = 0;
vector<Inventory*> inventory;
};
// Print all items in the inventory
void PrintInventory(vector<Item*> inventory);
// Dialogue to create a new item, then add that item to the inventory
vector<Item*> AddItemToInventory(vector<Item*> inventory);
// Dialogue to create a new book, then add that book to the inventory
vector<Item*> AddBookToInventory(vector<Item*> inventory);
// Dialogue to update the quantity of an item, then update that item in the inventory
vector<Item*> UpdateItemQtyInInventory(vector<Item*> inventory);
// Dialogue to remove a specific item, then remove that specific item from the inventory
vector<Item*> RemoveItemFromInventory(vector<Item*> inventory);
int main() {
vector<Inventory*> inventory1;
string usrInptOptn = "default";
string usrInptOptn2 = "default";
Inventory update;
update.UpdateItemQtyInventory();
while (true) {
// Get user choice
cout << "\nEnter (p)rint, (a)dd, (u)pdate, (r)emove, or (q)uit: ";
getline(cin, usrInptOptn);
// Process user choice
if (usrInptOptn.size() == 0) {
continue;
}
else if (usrInptOptn.at(0) == 'p') {
Inventory printer;
printer.PrintInventory();
update.SetInventory(inventory1);
}
else if (usrInptOptn.at(0) == 'a') {
cout << "\nEnter (b)ook or (p)roduce: ";
getline(cin, usrInptOptn2);
if (usrInptOptn2.at(0) == 'b') {
inventory1 = AddBookToInventory(inventory1);
inventoryUpdate.SetInventory(inventory1);
}
else if (usrInptOptn2.at(0) == 'p') {
inventory1 = AddItemToInventory(inventory1);
inventoryUpdate.SetInventory(inventory1);
}
else
{
continue;
}
}
else if (usrInptOptn.at(0) == 'u') {
inventory1 = UpdateItemQtyInInventory(inventory1);
}
else if (usrInptOptn.at(0) == 'r') {
inventory1 = RemoveItemFromInventory(inventory1);
}
else if (usrInptOptn.at(0) == 'q') {
cout << "\nGood bye." << endl;
break;
}
}
return 0;
}
I'm also getting additional errors, but I think they are coming from this main issue. What do I do to fix this?
Thanks!
Also, I'm using Visual Studio, but have checked with Code::Blocks to make sure it isn't a weird compiler issue.
Most of your functions look somehow similar to this:
void foo() {
std::vector<T> foo(std::vector<T> bar){
/*...*/
}
}
It looks like you try to declare a function inside the function (with the same name but different parameters and return type and sometimes with missing return type). Just dont do that, but just this:
std::vector<T> foo(std::vector<T> bar){
/*...*/
}

Exception handling trouble, why?

Here is my main:
int main() {
Inventory Master;
bool flag;
Customer Bob("Bob", "CreditCard.txt");
Customer Joe("Joe", "CreditCard.txt" );
Master.firststock( "inventory.txt" );
vector<Food> temp = Master._Inv;
cout <<"Hi, What would you like to buy today?" << endl;
for(unsigned int i=0; i<temp.size(); i++ ) {
cout << temp[i].name << " " << temp[i].quant << " " << temp[i].price << endl;
}
cout <<"\n";
Food Apple("Apples", .99, 10);
Food Orange("Oranges", .99, 10);
Food Chip("Chips", 3.00, 10);
cout <<"\nHi Bob" << endl;
flag = Bob.addCart(Apple, 7, &Master);
cout <<"Bob's total purchases are Currently: \n";
Bob.report();
flag = Bob.addCart(Orange, 2, &Master);
flag = Bob.addCart(Chip, 2, &Master);
Bob.report();
flag = Bob.removeCart();
Bob.report();
cout <<"Bob, ";
flag = Bob.checkout(&Master);
here is the following i implemented to remove food from my vector _Cart:
bool Customer::removeCart() {
bool flag;
int q = 0;
unsigned int i=0;
string remove;
cout << "\nWhat would you like to remove and how much would you like to remove?" << endl;
cin >> remove >> q;
for (i =0; i < _Cart.size(); i++) {
if(remove == _Cart[i].name) {
if (q >= 0) {
_Cart[i].quant -= q;
//inv->_Inv[i].quant += q;
cout <<"\nYou removed " << q << " " << remove <<" In your cart\n" << endl;
return true;
}
if (q < 0) {
cout << "Invalid number of " << remove << " being removed.\n" << endl;
return true;
}
}
else {
try {
throw remove;
}
catch (string param) {
cout << "\n" << remove << " doesn't exist in your cart\n" << endl;
}
return true;
}
}
My header containing the the function removeCart:
class Customer {
public:
Customer(string n, string fileName);
~Customer() { _Cart.clear(); };
bool addCart(Food f, int q, Inventory* inv);
bool removeCart();
void report();
bool checkout(Inventory* inv);
protected:
string remove;
string name;
int q;
int card;
double balance;
CreditCard _CC(int card,double balance);
vector<Food> _Cart;
};
Now for some reason when i call removeCart, entering "Apples" works but i noticed i made a food object called Apple so not sure why typing "Apples" works for being removed instead of "Apple". Also when i try "Orange" or "Chip" the exception is shown but as you can see in main i added Chip and Orange to Bob's Cart. I could appreciate the help.
You are making an object called Apple containing a member of type std::string which holds characters "Apples". Only your compiler knows that you called an object Apple but your program compare string "Apples" with your input. Same with Orange and Chip.
You've declared an object called Apple somewhere in your code.
You've then instantiated an instance of an Apple class and set the Apple::name member to 'Apples', a string.
You're not comparing the input with the class name, you're comparing the input with the member data of the Apple class.