Copying a specific field from a vector into another vector - c++

I am trying to make a basket system for a C++ program, and I am stuck with the task of obtaining the price from one vector in a separate class, and copying that price into the new "Basket" Vector. i have tried a number of workaround but I have gotten as far as having it return the error message that the identifier is undefined, even though the vector is public in the class.
the header file :
class Item {
private:
int _ItemNo;
string _category, _description;
double _price;
double _VAT = _price*0.2;
double _subtotal = _price + _VAT;
};
class ItemMenu {
public:
vector<Item> _Items;
ItemMenu();
void displayMenu();
};
//Class for ordering from the menu
class Ordering {
private:
vector<Item> _Basket;
int quantity;
double total;
public:
Ordering();
Ordering(int quantity, double total);
void placeOrder(const vector<Item> &Items);
The implementation file:
ItemMenu::ItemMenu() {
ifstream fin("Menu.txt");
if(fin) {
while(!fin.eof()) {
string _ItemNoTemp;
getline(fin, _ItemNoTemp, ':');
int _ItemNo = stoi(_ItemNoTemp);
string _category;
getline(fin, _category, ':');
string _description;
getline(fin, _description, ':');
string _priceTemp;
getline(fin, _priceTemp);
double _price = stod(_priceTemp);
if(!fin.eof()) {
_Items.push_back(Item(_ItemNo,
_category, _description, _price));
};
fin.peek();
}
fin.close();
}
}
//Method to display the each item
void ItemMenu::displayMenu() {
for(int i = 0; i < _Items.size(); ++i) {
_Items[i].display();
}
cout << endl;
}
Ordering::Ordering() { }
void Ordering::placeOrder() {
int select;
cout << "Please enter an item number: ";
cin >> select;
Item I;
i._subtotal = _Items[select]._subtotal;
_Basket.push_back(i);
}
It is in the ordering class that the basket vector is in, and I am trying to get the subtotal for the items, so that I may calculate the total by summing the values in the vector. This is also where the error saying that _Items is undefined appeared. I am new to programing and haven't really been able to find a clear source for how vectors work between classes depending on where they are declared.

Something like this should work
void Ordering::placeOrder(
const vector<Item>& items ) {
int select;
cout << "Please enter an item number: ";
cin >> select;
cItem i;
i._price = items[ select ]._price;
_Basket.push_back( i );
}

You don't actually pass an ItemMenu object to this function. That's why you are getting an undefined error.
Instead of this
void Ordering::placeOrder() {
int select;
cout << "Please enter an item number: ";
cin >> select;
_Basket.push_back(_Items[select]._subtotal);
}
You would want to do this
void Ordering::placeOrder(ItemMenu yourItemMenuVarible) {
int select;
cout << "Please enter an item number: ";
cin >> select;
_Basket.push_back(_Items[select]._subtotal);
}
then when you call it you would pass it the ItemMenu variable you defined and I think that should fix it.
I would also recommend you not have variables like the vector public, it not a very good practice for security reasons. Learning good habits now will help you in the future. The idea of keeping them private is called Encapsulation here are some sources on the topic
https://www.geeksforgeeks.org/encapsulation-in-c/
https://www.tutorialspoint.com/cplusplus/cpp_data_encapsulation.htm#:~:text=Encapsulation%20is%20an%20Object%20Oriented,from%20outside%20interference%20and%20misuse.&text=This%20means%20that%20they%20can,other%20part%20of%20your%20program.

Thanks for all the help guys i ended up fixing it with your help the code is below.
Header File:
class Ordering {
private:
vector<Item> _Basket;
int quantity;
double total;
public:
Ordering();
Ordering(int quantity, double total);
void placeOrder(vector<Item> Items);
};
Implementation:
Ordering::Ordering() { }
void Ordering::placeOrder(vector<Item> _Items) {
int select;
Item i;
char cont;
do{
cout << "Please enter an item number: ";
cin >> select;
i._ItemNo = _Items[select-1]._ItemNo;
i._description = _Items[select-1]._description;
i._subtotal = _Items[select-1]._subtotal;
_Basket.push_back(i);
cout << i._subtotal;
cout << "Do you want to add another Item? (y/n): ";
cin >> cont;
}while(cont == 'y' || cont == 'Y');
for (int i; i < _Basket.size(); i++) {
cout << _Basket[i]._ItemNo << ':' << _Basket[i]._description
<< ':' << char(156) << _Basket[i]._subtotal << endl;
};
}
Main:
int main() {
cout << "--------------------------------" << endl;
cout << "Billing Program" << endl <<
"--------------------------------" << endl;
Ordering start;
ItemMenu display;
display.displayMenu();
start.placeOrder(display._Items);
}

Related

Printing value in void to other void

I'm trying to print a value found in the "getvalue" void in the "show" void. I get an error:
error: 'Students' was not declared in this scope
#include <iostream>
using namespace std;
int studentNumber=0;
int testNumber=0;
struct Student
{
string name,grade;
int studentNo,*testResults;
double average;
};
void getValue()
{
cout << "Enter the number of students: ";
cin >> studentNumber;
cout << "Enter the number of tests: ";
cin >> testNumber;
Student* Students = new Student[studentNumber];
for(int i=0; i< studentNumber; i++)
{
cout<< "\n" << "Enter the name of the " << i+1 << ". student: ";
cin >> Students[i].name;
cout<< "\n" << "Enter the number of the " << i+1 << ". student: ";
cin >> Students[i].studentNo;
Students[i].testResults = new int[testNumber];
for(int z=0; z<testNumber; z++)
{
cout<< "\n" << "Enter the " << z+1 << ". exam grade of the " << i+1 << ". student: " ;
cin >> Students[i].testResults[z];
}
}
}
void show()
{
for(int i=0; i < studentNumber; i++)
{
cout<< "\n" << Students[i].name;
cout<< "\n" << Students[i].studentNo;
for(int z=0; z<testNumber; z++)
{
cout<< "\n" <<Students[i].testResults[z];
}
}
}
int main()
{
getValue();
show();
}
I'm trying to show the obtained values ​​in another void called "show" but failed. (The general structure of the code that must be in a different void must be another void named "show" in my homework)
You have to pass the value.
It can be done via reference:
// omit
void getValue(Student*& Students) // add reference argument
{
cout << "Enter the number of students: ";
cin >> studentNumber;
cout << "Enter the number of tests: ";
cin >> testNumber;
// don't declare here and use the arugment
Students = new Student[studentNumber];
// omit
}
void show(Student* Students) // add argument (need not be reference)
{
// omit
}
int main()
{
// add variable for arguments and use that
Student* s;
getValue(s);
show(s);
}
Or via global variable:
// omit
// declare variable here (as global)
static Student* Students;
void getValue()
{
cout << "Enter the number of students: ";
cin >> studentNumber;
cout << "Enter the number of tests: ";
cin >> testNumber;
// don't declare here and use the global variable
Students = new Student[studentNumber];
// omit
}
void show()
{
// omit
}
int main()
{
getValue();
show();
}
Instead of raw arrays, it might be good to use std::vector<Student>. It'd be easy to replace:
Student* Students = new Student[studentNumber];
with:
#include <vector>
...
std::vector<Student> Students(studentNumber);
(pretty much everything else should be the same) and then for the actual error you're seeing, since the Students array only exists inside the scope of the getValue() function, you'll need to return it so that show() can the array too. Consider changing the code to something like (assuming you're using the vector):
std::vector<Student> getValue() {
...
return Students;
}
void show(std::vector<Student> Students)
...
}
int main() {
auto Students = getValue();
show(Students);
}

How to allow user input in objects and classes?

Consider the following code:
#include <iostream>
using namespace std;
class inventory
{
public:
~inventory()
{
cout << "This Object is being destroyed" << endl;
}
inventory()
{
itemNumber = 0;
quantity= 0;
cost= 0;
}
inventory(int itemNumber1, int quantity1, double cost1)
{
setItemNumber(itemNumber1);
setQuantity(quantity1);
setCost(cost1);
}
void setItemNumber(int itemNumber2)
{
itemNumber=itemNumber2;
}
bool setQuantity(int quantity2)
{
bool userTrue = true;
bool userFalse = false;
if (quantity2 < 0)
{
quantity = 0;
return userFalse;
}
else
{
quantity= quantity2;
return userTrue;
}
}
bool setCost(double cost2)
{
bool userTrue = true;
bool userFalse = false;
if (cost2 < 0.0)
{
cost = 0.0;
return userFalse;
}
else
{
cost= cost2;
return userTrue;
}
}
double getTotalCost(int quantity, double cost)
{
int total;
total = (quantity * cost);
return total;
}
private:
int itemNumber;
int quantity;
double cost;
};
int main()
{
int itemNumberInput;
int quantityInput;
double costInput;
cout << "Enter the Item Number: " << endl;
cin >> itemNumberInput;
cout << "Enter the Quantity : " << endl;
cin >> quantityInput;
cout << "Enter the Cost : " << endl;
cin >> costInput;
inventory *pointerA, *pointerB;
pointerA = new inventory;
pointerB = new inventory(inventory(itemNumberInput , quantityInput , costInput));
inventory firstObject(itemNumberInput,quantityInput,costInput);
int itemNumberInput1;
int quantityInput1;
double costInput1;
cout << "Enter the Item Number: " << endl;
cin >> itemNumberInput1;
cout << "Enter the Quantity : " << endl;
cin >> quantityInput1;
cout << "Enter the Cost : " << endl;
cin >> costInput1;
inventory secondObject(itemNumberInput1,quantityInput1,costInput1); // not sure if thats correct
cout << secondObject.setItemNumber(); // not working
cout << secondObject.setQuantity(); // not working
cout << secondObject.setCost(); // not working
return 0;
}
The code above is supposed to take three user inputs, and send them to the classes, and the classes will do their job.
I'm currently stuck at the end where its giving me an error.
In the second object where the values are asked from the user, it should send these values to the classes.
Instead, I'm getting the error.
How can I resolve this problem?
Here is the fixed code:-
#include <iostream>
using namespace std;
class inventory
{
public:
~inventory()
{
cout << "This Object is being destroyed" << endl;
}
inventory()
{
itemNumber = 0;
quantity= 0;
cost= 0;
}
inventory(int itemNumber, int quantity, double cost)
{
this->itemNumber = itemNumber;
this->quantity = quantity;
this->cost = cost;
}
void setItemNumber(int itemNumber)
{
this->itemNumber=itemNumber;
}
bool setQuantity(int quantity)
{
bool userTrue = true;
bool userFalse = false;
if (quantity < 0)
{
this->quantity = 0;
return userFalse;
}
else
{
this->quantity= quantity;
return userTrue;
}
}
bool setCost(double cost)
{
bool userTrue = true;
bool userFalse = false;
if (cost < 0.0)
{
this->cost = 0.0;
return userFalse;
}
else
{
this->cost= cost;
return userTrue;
}
}
double getTotalCost(int quantity, double cost)
{
return quantity * cost;
}
private:
int itemNumber;
int quantity;
double cost;
};
int main()
{
int itemNumberInput;
int quantityInput;
double costInput;
cout << "Enter the Item Number: " << endl;
cin >> itemNumberInput;
cout << "Enter the Quantity : " << endl;
cin >> quantityInput;
cout << "Enter the Cost : " << endl;
cin >> costInput;
inventory *pointerA, *pointerB;
pointerA = new inventory;
pointerB = new inventory(inventory(itemNumberInput , quantityInput , costInput));
inventory firstObject(itemNumberInput,quantityInput,costInput);
int itemNumberInput1;
int quantityInput1;
double costInput1;
cout << "Enter the Item Number: " << endl;
cin >> itemNumberInput1;
cout << "Enter the Quantity : " << endl;
cin >> quantityInput1;
cout << "Enter the Cost : " << endl;
cin >> costInput1;
// The below line is correct
// inventory secondObject(itemNumberInput1,quantityInput1,costInput1);
//Alternatively
inventory secondObject;
secondObject.setItemNumber(itemNumberInput1);
secondObject.setQuantity(quantityInput1);
secondObject.setCost(costInput1);
delete pointerA; // delete dynamically allocated memory to avoid memory leak
delete pointerB;
return 0;
}
Well you've constructed 'secondObject' object using the 3-arg constructor, using the user-entered values as parameters. Therefore, the member variables of this object are being set via the constructor and using the 'set' methods aren't really necessary. In your case, the set methods would be useful if you wanted to change the values later on. For example, lets pretend the user enters 10, 10, and 2.5 for the values. You're then using the constructor to construct the object with those values. The only difference is you're placing those values into variables first. But it works the same way. If you wanted to change the value of quantity later on, you could do secondObject.setQuantity(2); And the quantity for that object is now set to 2. The reason why your calls to .set aren't working is because you need to pass in parameters to these methods i.e. the value you want to set it to.
In regard to the destructor method being printed, objects are destroyed when they go out of scope so that the memory is released. Normally, nothing would happen in terms of output- the object would just go out of scope and the compiler would free up the memory and go about its' business. However, you've coded a custom destructor that prints out 'The Object is being destroyed', which it is at the end of the main. It's likely your constructor is working fine, I'm just not sure what you expect to be happening. I'd also suggest you read up on memory leaks in C++, especially in regard to the 'new' keyword.

class pointer unitialized local variable

Recently in my c++ class we have learned about pointers and classes.
I'm trying to make a program that has a class Student, which we will point to give each student a name and test score.
After entering both name and test score, they are sorted and then listed in order of highest to lowest.
I believe all my syntax to be correct, however I am still learning. The problem I am having is that the first time I use my class I get an uninitialized local variable error, any help on how to fix this?
#include "stdafx.h"
#include <iostream>
#include <string>
#include <array>
using namespace std;
class Student {
private:
double score;
string name;
public:
void setScore(double a) {
score = a;
}
double getScore() {
return score;
}
void setName(string b) {
name = b;
}
string getName() {
return name;
}
};
void sorting(Student*, int);
int main()
{
Student *students;
string name;
int score;
int *count;
count = new int;
cout << "How many students? ";
cin >> *count;
while (*count <= 0) {
cout << "ERROR: The number of students must be greater than 0.\n";
cin >> *count;
}
for (int i = 0; i < *count; i++) {
cout << "Please enter the students name: ";
cin >> name;
students[i].setName(name);
cout << "Please enter " << students[i].getName() << "'s score: ";
cin >> score;
while (score < 0) {
cout << "ERROR: Score must be a positive number.\n";
cin >> score;
}
students[i].setScore(score);
}
sorting(students, *count);
for (int i = 0; i < *count; i++) {
cout << students[i].getName() << ": " << students[i].getScore() << endl;
}
system("PAUSE");
return 0;
}
void sorting(Student *s, int size) {
for (int i = 0; i < size; i++) {
for (int j = i; j < size; j++) {
if (s[j].getScore() > s[(j + 1)].getScore()) {
int tmp = s[(j + 1)].getScore();
s[(j + 1)].setScore(s[j].getScore());
s[j].setScore(tmp);
string tmp1 = s[(j + 1)].getName();
s[(j + 1)].setName(s[j].getName());
s[j].setName(tmp1);
}
}
}
}
First off, your Student class can be simplified to this:
struct Student {
double score;
std::string name;
};
Because the accessors do absolutely nothing. I've also added the std:: prefix because using namespace std is considered a bad practice.
Now, instead of using the pointer to store the students, include vector and use that:
std::cout << "How many students? ";
int count;
std::cin >> count;
std::vector<Student> students(count);
The loading routine can also be simplified given the absence of accesors:
for (auto& student : students) {
std::cout << "Please enter the students name: ";
std::cin >> student.name;
std::cout << "Please enter " << student.name << "'s score: ";
std::cin >> student.score;
while (score < 0) {
std::cout << "ERROR: Score must be a positive number.\n";
std::cin >> student.score;
}
}
And actually once you have that, you could just put it in istream& operator>>(istream&, Student&) and reduce it to:
std::copy_n(std::istream_iterator<Student>(std::cin), students.size(), students.begin());
No need now for temporary variables anymore (and even if you want to use them, they should be defined just before the use, so inside of the loop).
The last thing is your sorting routine. First off, there's std::sort that you can use instead if you simply provide a comparator:
std::sort(
begin(students),
end(students),
[](Student const& a, Student const& b) { return b.score < a.score; }
);
If you insist on writing the sorting routine yourself, at least use std::swap.

i need to create array on the heap aby to hold a specific number set by the user

hey guys new to this site looking some help for my final project i having to create a project that takes car data saves it to the heap and has a bunch of error checking not all the way done but getting there. but i cant grasp the heap and how to input it correctly into my code here is what i have. and it has to be under 175 lines and i still have to have it ask user if they want to write to a new file or existing. thanks ahead once again question is how do i create array on the heap able to hold the number of vech specified buy user.
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
class carData4
{
public:
void setYear(int& year);
void setMake(string make);
void setModel(string);
void setMileage(int& mileage);
void setName(string name);
void setNumber(string number);
int getYear(){ return itsYear; }
string getMake(){ return itsMake; }
string getModel(){ return itsModel; }
int getMileage(){ return itsMileage; }
string getName(){ return itsName; }
string getNumber(){ return itsNumber; }
private:;
int itsYear;
string itsMake;
string itsModel;
int itsMileage;
string itsName;
string itsNumber;
};
void carData4::setYear(int & year)
{
do
{
cout << "Enter the cars Year from 1910 and 2014:\n ";
cin >> year;
itsYear = year;
if (year < 1910 || year > 2014)
cout << "INVALID! please enter a correct year! ";
} while (year < 1910 || year > 2014);
}
void carData4::setMake(string make)
{
cout << "Enter the cars make:\n\n";
cin >> make;
itsMake = make;
}
void carData4::setModel(string model)
{
cout << "Enter the cars model:\n\n";
cin >> model;
itsModel = model;
}
void carData4::setMileage(int & mileage)
{
do{
cout << "Enter the cars mileage:\n\n";
cin >> mileage;
itsMileage = mileage;
}
while (mileage <0 || mileage >10000000);
cout << "NOPE enter within 0 and million miles.\n\n";
cin >> mileage;
itsMileage = mileage;
}
void carData4::setName(string name)
{
cout << "Enter your name :";
cin >> name;
itsName = name;
}
void carData4::setNumber(string number)
{
cout << "Enter Your phone number (XXX)XXX-XXXX:";
cin >> number;
itsNumber = number;
}
int main()
{
carData4 car1;
int year, mileage, numCars, ;
string make, model, name, number;
cout << "How many vehicles are to be added to inventory?.\n\n";
cin >> numCars;
for (int i = 1; i < numCars; i++){
car1.setYear(year);
car1.setMake(make);
car1.setModel(model);
car1.setMileage(mileage);
car1.setName(name);
car1.setNumber(number);
cout << car1.getYear() << "\t" << car1.getMake() << "\t " << car1.getModel()
<< "\t" << car1.getMileage() << "\t " << car1.getName() << "\t " << car1.getNumber() << endl;
}
system("PAUSE");
return EXIT_SUCCESS;
}
i add some is this correct????????????????
int main()
{
carData4 car1; // *car1=new carData4[numCars];
int year,mileage,numCars;
double *cars;
string make,model,name,number;
cout << "How many vehicles are to be added to inventory?.\n\n";
cin >>numCars;
cars = new double [numCars];
for (int i=1; i<numCars;i++){
car1.setYear(year);
car1.setMake(make);
car1.setModel(model);
car1.setMileage(mileage);
car1.setName(name);
car1.setNumber(number);
cout << car1.getYear() << "\t" << car1.getMake() << "\t " << car1.getModel()
<< "\t" << car1.getMileage() << "\t " << car1.getName() << "\t " << car1.getNumber() <<endl;
delete [] cars;
}
system("PAUSE");
return EXIT_SUCCESS;
}
The best way to have dynamic storage for your use case would be to use a vector, like so:
std::cout << "How many vehicles are to be added to inventory?.\n\n";
std::size_t n;
std::cin >> n;
std::vector<carData4> cars ( n );
//gives you:
//cars[0] ... cars[ n-1 ]
http://en.cppreference.com/w/cpp/container/vector
To dynamically allocate an array based on user input:
unsigned int array_capacity;
cout << "Enter array capacity: ";
cin >> array_capacity;
int * my_array = new int[array_capacity];
Remember to delete the array using delete [] my_array;.
Edit 1: using Car class
CarData4 * my_cars = new CarData4[numCars];

Searching for a string in an array

I have "items" in an "inventory" array, the inventory array is a struct composed of several different parts however I want to be able to search for a certain part of the array by using the item name alone (so I can make functions to delete, purchase, etc.) I was wondering how I would go about doing so and if it would instead be easier to convert the struct to a class instead if need be. Keep in mind a good amount of it is still a work in progress, I'm specifically aiming for the removeItem function currently however. Thanks in advance for any and all help!
my code is here:
#include "integerstore.h"
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
void removeItem(Item);
int buyItem(Item, int);
int sellItem(Item, int);
void stockReport(Item);
struct Item
{
string name;
float cost;
float price;
int quantity;
};
int main()
{
Item inventory[100];
int total = 0;
string cmd;
cout << "Welcome to inventory management. To add a new inventory item type add, to remove and item from inventory type remove, to add to inventory quantity type buy, to mark a sold item type sell, to see the current inventory report type report and to end the program type stop" << endl;
do
{
cin >> cmd;
if (cmd == "add")
{
cout << "Enter the new item's name";
cin >> inventory[i].name;
cout << endl;
cout << "Enter the new item's cost";
cin >> inventory[i].cost;
if (inventory[i].cost <= 100.00)
{
break;
}
else
{
cout << "Cost of item may not exceed 100.00, please reenter.";
cin.clear();
}
cout << endl;
cout << "Enter the new item's selling price";
cin >> inventory[i].price;
if (inventory[i].price <= 100.00)
{
break;
}
else
{
cout << "Selling price may not exceed 100.00, please reenter.";
cin.clear();
}
cout << endl;
i++;
}
else if (cmd == "remove")
removeItem(inventory[100]);
else if (cmd == "buy")
buyItem(inventory[100], total);
else if (cmd == "sell")
sellItem(inventory[100]);
else if (cmd == "report")
stockReport(inventory[100]);
else if (cmd != "stop")
cout << "invalid";
}
while (cmd != "stop");
system ("pause");
return 0;
}
int buyItem(Item w, int w2)
{
string itemName;
cout << "Enter the item name of which you wish to add more stock to" << endl;
cin >> itemName;
}
int sellItem(Item x, int x2)
{
}
void removeItem (Item y)
{
string itemName;
cout << "Enter the item name you wish to remove from the inventory" << endl;
cin >> itemName;
}
void stockReport(Item z)
{
}
You can use a map<string, Item> (you might want to remove name from the Item struct).
Then you can use it for instance like this:
map<string, Item> inventory;
// Add
inventory["stuff"].cost = 12;
// ...
// Get
string name;
cin >> name;
Item myItem = inventory[name];