Hi I am attempting to read data into a vector of objects but I am having trouble doing so. I have created a class and a vector of that class. When I try to read data into the the vector I get class Bank Statements has no member and then the variables i attempt to read in.
#include <iostream>
#include<vector>
#include <string>
using namespace std;
class Bank_Statement
{
public:
Bank_Statement();
Bank_Statement(int d, double bal, string desc);
private:
string description;
double balance;
int day;
};
Bank_Statement::Bank_Statement(int d, double bal, string desc)
{
description = desc;
balance = bal;
day = d
}
int main(){
Bank_Statement statement1;
cin >> statement1.d >> statement1.bal >> statement1.desc;
vector<Bank_Statement> user_statements;
int day_of_month;
for (day_of_month = 0, day_of_month < user_statements.size(); day_of_month++){
user_statements.push_back(statement1);
}
return 0;
}
The argument names of the constructor are not data members of the class. When you did:
cin >> statement1.d >> statement1.bal >> statement1.desc;
That is not right because those aren't members declared in the class. Use description, balance, and day respectively instead.
It doesn't even enter the loop. When the vector is created, its size is zero. This means that the expression day_of_month < user_statements.size() (the loop condition) will always be false.
You should read the input in the loop, something like
Bank_Statement statement;
std::vector<Bank_Statement> user_statements;
while (std::cin >> statement.d >> statement.bal >> statement.desc)
{
user_statements.push_back(statement);
}
Thats because of the condition day_of_month < user_statements.size(). Initially vector is empty and does not satisfy the condition to do a push_back operation on the vector.
Related
I have been working on a project for my computer science class and have encountered an issue with the code working. I am shown no error except when I try to compile and I get an error that reads:
Exception thrown: write access violation.
_Left was 0xCCCCCCCC.
The purpose of my project is to take a list of names from an external file, read them into an array, sort said array and then output the sorted list all while using a class for the code.
Here is a copy of my code and I would like to extend my gratitude to whoever can help me through my issue:
**Header File**
#include <iostream>
using namespace std;
class person
{
public:
person();
bool get(ifstream&);
void put(ofstream&);
private:
int capacity = 0;
string first_name[CAPACITY];
string last_name[CAPACITY];
int age[CAPACITY];
};```
**Header function definitions cpp file**
#include<iostream>
#include<string>
#include<fstream>
#include<cstdlib>
const int CAPACITY=20;
using namespace std;
#include "Person.h"
//Names constructor
//Postcondition both first name and last name initialized to zero
person::person()
{
first_name[CAPACITY] = "";
last_name[CAPACITY] = "";
age[CAPACITY]=0;
}
bool person::get(ifstream& in)
{
in >> first_name[CAPACITY] >> last_name[CAPACITY] >> age[CAPACITY];
return(in.good());
}
void person::put(ofstream &out)
{
out << first_name[CAPACITY] << last_name[CAPACITY] << age[CAPACITY];
}
**cpp file which holds main**
#include<iostream>
#include<cstdlib>
#include<fstream>
#include<string>
const int CAPACITY = 20;
using namespace std;
#include "Person.h"
void pop(string *xp, string *yp);
void sort(string name[CAPACITY], int count);
int main()
{
class person names[CAPACITY];
ifstream infile;
ofstream outfile;
string filename;
string name[CAPACITY];
int n = 0;
cout << "Enter the file name you wish to open" << endl;
cin >> filename;
infile.open(filename + ".txt");
outfile.open("Person_New.txt");
if (infile.fail())
{
cout << "The file requested did not open" << endl;
exit(1);
}
while (!infile.eof())
{
names[n].get(infile);
n++;
}
sort(name, CAPACITY);
for (int i = 0; i < CAPACITY; i++)
{
names[i].put(outfile);
}
cout << "The file has been created" << endl;
infile.close();
}
void pop(string *xp, string *yp)
{
string temp = *xp;
*xp = *yp;
*yp = temp;
}
void sort(string name[CAPACITY], int count)
{
int i, j;
for (i = 0; i < count - 1; i++)
{
for (j = 0; j < count - i - 1; j++)
{
if (name[j] > name[j + 1])
{
pop(&name[j], &name[j + 1]);
}
}
}
}
Once again Thank you for any support
It sounds to me like the compiler is getting upset that you are trying to write (i.e. assign a value) at an address that you do not have permission to access. I believe your constructor for the class person might be at fault because of how this class stores its variables, as well as the class header:
Constructor for the class person:
`person::person(){
first_name[CAPACITY] = "";
last_name[CAPACITY] = "";
age[CAPACITY] = 0;
}`
Class header for the class person:
`class person{
public:
//stuff
private:
int capacity = 0;
std::string first_name[CAPACITY];
std::string last_name[CAPACITY];
int age[CAPACITY];
//more stuff
}`
C++ is very specific about its naming conventions, so it makes a distinction between capacity and CAPACITY. Because of this, the variable CAPACITY is not defined within the Person.h file.
Also, because CAPACITY is set to a fixed value in your Person.cpp file, whenever you use first_name[CAPACITY], last_name[CAPACITY], or age[CAPACITY] to assign new values, you are only updating the values at the index equal to CAPACITY unless you update the value of CAPACITY itself. In the code you provided, CAPACITY is equal to 20, so your program attempts to update exclusively index 20 with each method call. This will likely cause issues since the person class only attempts to make its arrays on the runtime stack, with a size of 0 each.
Separately, it seems like you want an array of people, but it appears that you are attempting to use a single person object to store the names and ages of multiple people by making these all arrays. Instead, I would recommend making first_name, last_name, and age not arrays, but rather single variables. Then, you can manipulate an array of type person using your CAPACITY variable. You got pretty close, but you can instead declare it as person myPersonArray[CAPACITY] (no need to mention "class" in front of it -- just be sure that you have #include "Person.h" in your main.cpp file). When you want to update a specific person, you can perform an operation like myPersonArray[updateThisIndexNum].update(newFirstName, newLastName, newAge) or some logical equivalent.
As a final note, I almost always highly recommend against using !infile.eof() to control your while loop when reading any file because eof() only indicates whether you have tried to read past the end of an input file. I would highly recommend checking out this post on Stack Overflow where people far more knowledgeable than I explain exactly why this is usually dangerous and how to avoid it.
I am writing a program using an array of structures to store a name, id number, and an array of test scores for a certain amount of students. Both the array of structures and the array of test scores member need to be dynamically allocated. I've gotten down to the function that allows the user to input test scores for each student, however I am having problems with the cin in the last function (getScores function). When using Linux I get a segmentation fault, so I'm assuming it has something to do with the dynamically allocated tests array that is a member of the structure, I just can't see it. I'm wondering how I can go about debugging it and an explanation of why this is actually occurring so I can avoid it in the future.
//Preprocessor Directives
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
//Structure declaration
struct Students
{
string name; //Student name
int idNum; //Student ID number
double *tests; //Pointer to an array of test scores
};
//Function prototypes
Students *getStudents(int &);
double *getTests(int &);
void getInfo(string &, int &, int);
void getScores(double &, string, int);
//Main program section
int main ()
{
int numStudents = 0;
int numTests = 0;
Students *studentFiles = NULL;
//Call the getStudents function
studentFiles = getStudents(numStudents);
//Call the getTests function
studentFiles->tests = getTests(numTests);
for(int i = 0; i < numStudents; i++)
{
//Call the getInfo function
getInfo(studentFiles[i].name, studentFiles[i].idNum, i+1);
}
for(int i = 0; i < numStudents; i++)
{
for(int j = 0; j < numTests; j++)
{
getScores(studentFiles[i].tests[j], studentFiles[i].name, j);
}
}
delete [] studentFiles;
delete [] studentFiels->tests;
return 0;
}
Students *getStudents(int &numStudents)
{
Students *studentFiles = NULL;
//Prompt the user for the number of students
cout<<"Enter the number of students: ";
cin>>numStudents;
//Dynamically allocate an array of structs, one for each student
studentFiles = new Students[numStudents];
return studentFiles;
}
double *getTests(int &numTests)
{
double *tests = NULL;
//Prompt the user for the number of tests
cout<<"Enter the number of tests: ";
cin>>numTests;
cin.ignore();
//Dynamicall allocate an array of integers, one for each test
tests = new double[numTests];
return tests;
}
void getInfo(string &name, int &idNum, int index)
{
//Prompt for each student's name and id number
cout<<"Enter the name of student #"<<index<<": ";
getline(cin, name);
cout<<"Enter the id number of student #"<<index<<": ";
cin>>idNum;
cin.ignore();
}
void getScores(double &test, string name, int numTest)
{
cout<<name<<endl;
cout<<numTest<<endl;
//Prompt for each test score for each student
cout<<"Enter "<<name<<"'s score for test #"<<numTest+1<<": ";
cin>>test;
}
One error is that you access a member of deleted object studentFiles. Reverse the lines to fix that:
delete [] studentFiles->tests;
delete [] studentFiles;
Ideally, use std::vector<> instead of dynamically allocating and releasing memory manually.
Also note, that the code only initializes Student::tests of the first member of the array, the rest of Student objects have this member uninitialized. The result of expression studentFiles[i].tests[j] is undefined and is likely to cause a crash.
You need to initialize Student::tests member of each Student. And when done, deallocate Student::tests of each Student.
Hello everyone and sry in advance for the newbie question but i didn't find any topic specific to my problem. I have a text file of products as shown below:
//No. //Description //Price
100 Office_seat 102.99
200 Desk 224.99
300 Computer_desk 45.49
400 Desk_Lamb 23.99
500 Bookcase 89.49
i want to read it and save it in an array from which i will search for the Product_pin later and calculate the total price of a client's purchase.
tried something like the code i am posting but i think i am starting it all wrong. I would be gratefull for any advice.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
ifstream file("Proionta.txt");
if(file.is_open())
{
string myArray[15];
for(int i=0;i<15;i++)
{
file>>myArray[i];
}
}
system ("pause");
}
Should i try to make a function to put the code in it?
Let's start out with the record modeling concept, then get primitive.
You want to model the text line as a record:
struct Record
{
unsigned int number;
std::string description;
double price;
};
The next step would be to overload operator>> for the Record:
struct Record
{
unsigned int number;
std::string description;
double price;
friend std::istream& operator>>(std::istream& input, Record& r);
};
std::istream& operator>>(std::istream& input, Record& r)
{
input >> r.number >> r.description >> r.price;
return input;
}
Using the above code, you can read in a file:
std::vector<Record> database;
Record r;
while (my_text_file >> r)
{
database.push_back(r);
}
Edit 1: Without struct
Let's say you don't know about how to use class or struct.
Each field can be read separately:
unsigned int number;
std::string description;
double price;
while (my_text_file >> number >> description >> price)
{
// Do something with number, description, price
}
Edit 2: Arrays vs. vector
Many assignments require you to do something with the data, like averages or searches. This usually requires you to save the data.
Two popular containers (from a student's point of view) are the array and std::vector.
Arrays are not a good choice, because with File I/O, you're never quite sure how many records there are and arrays like to be static in capacity (never changing). So you will need to do the resizing yourself:
static const unsigned int initial_capacity = 16U;
Record database[initial_capacity];
unsigned int capacity = initial_capacity;
Record r;
unsigned int items_read = 0;
while (my_text_file >> r)
{
if (items_read < capacity)
{
database[items_read] = r;
++items_read;
}
else
{
// Allocate new, larger array
// Copy items from old array to larger array.
// Update capacity variable.
// Delete old array
// Change database pointer to new array
}
}
A nice feature of std::vector is that you can access it like an array, and it will automatically increase in capacity as needed.
I'm a bit confused as to how vectors work. What I'm trying to do is create a vector of 5 TaxBill objects. Then, what I want to do is read from an input file that has the names and different tax rates for 5 states. I want to store the name of the state in the object and the tax rates of the state in an array in int main().
Here's the input file called "Tax Rates.dat". The numbers are the sales, property and income tax rate, respectively, for each state.
TEXAS .0825 .02 -.03
MARYLAND .065 .04 .05
OHIO .03 .025 .03
CALIFORNIA .095 .055 .045
MAINE .02 .015 .02
Here's my class interface called "Tax Bill.h".
using namespace std;
class TaxBill
{
public:
void setValue(string, int);
void dataValid(double&, double&, double&);
private:
string Name;
int index;
double taxBill;
}
Here's my class implementation called "Tax Bill.cpp".
#include "Tax Bill.h"
void TaxBill::setValue(string name, int x)
{}
void TaxBill::dataValid(double& a, double& b, double& c)
{
if(a < 0)
a = 0;
if(b < 0)
b = 0;
if(c < 0)
c = 0;
return;
}
Here's my main source code so far.
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <vector>
#include "Tax Bill.h"
using namespace std;
int main()
{
const int SALARY = 100000,
HOUSE = 246000,
PURCHASE = 36000;
ifstream fin;
fin.open("Tax Rates.dat");
vector <TaxBill> someVector (5);
double sales,
property,
income;
double taxRates[5][3];
string name;
if(!fin)
return 0;
else
{
for(int i = 0; fin >> name >> sales >> property >> income; i++)
{
dataValid(sales, property, income);
taxRates[i][0] = sales;
taxRates[i][1] = property;
taxRates[i][2] = income;
}
}
The for loop is where I want to store the name of the state read from the input file and i into the string Name and index of the class object. The reason for the index is because later in the program I want to sort the objects in the vector alphabetically but not the array where the corresponding tax rates are stored.
I also don't want to use the function push_back().
I guess my question is, how do I make an vector of 5 class objects and access them?
Please keep in mind that my program is hardly complete and it's this one hurdle that's holding me back.
Here example of using vector from your code. Here you declare
vector <TaxBill> someVector (5);
So now, you have someVector[0] - [4] (5 in total). To use it, actually you just have to assign it like an normal array.
someVector[0].{insert property here}
But wait, in your class, there is no clear way to set the string Name and Index. So i think you forget to place it here, hence i make my own in the class.
class TaxBill
{
public:
void setValue(string Name, int Index){
name = Name; index = Index;
}
void dataValid(double&, double&, double&);
private:
string name;
int index;
double taxBill;
}
Now to use the vector, i just used the property this way
someVector[0].setValue("someName",1);
Tada, you get it to works. Btw, i dont know why you declare a procedure in the class, but you want to used it multiple times in main program. I mean this one
dataValid(sales, property, income);
to used it, i suggest you make a procedure in main program rather than in class and anyway that line should produce an error anyway. :)
I am doing the following with my program:
1) Write the class definition for a class named Employee with name and salary as employee objects. The class contains two member functions: the constructor and a function that allows a program to assign values to the data members.
2) Add two member functions to the Employee class. One member function should allow any program using an employee object to view the contents of the salary data member. The other member function should allow the program to view the contents of the employee name data member.
3) Add another member function to the Employeeclass. The member function should calculate an employee objects new salary, based on a raise percentage provided by the program using the object. Before calculating the raise, the member function should verify that the raise percentage is greater than or equal to zero. If the raise percentage is less than zero, the member function should display an error message.
4) Write a main function that will create an array of employee objects, assign values to the objects, display the names and current salaries for all objects, ask user for the raise percentage and then calculate and display new salaries for all objects.
However, I receive -2 as my new salary after I input the data from the keyboard. I figured another set of eyes could see what I can't and would highly appreciate if someone can lend a hand, or at least steer me in the right direction. Perhaps it is a logic error, or something wrong with my declarations. Thank you for your time.
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
class EMPLOYEE
{
public:
EMPLOYEE();//
EMPLOYEE(string name, int salary);//
public:
string name;//name to be input
int salary;//salary to be input
int percentage_raise;
int updated_salary;
public:
int enter_values();
int output_values();
int NEW_SALARY();
};
//default constructor
EMPLOYEE::EMPLOYEE()
{
name = "";
salary = 0;
}
//constructor with name/salary variables
EMPLOYEE::EMPLOYEE(string NAME, int SALARY)
{
name= NAME;
salary= SALARY;
}
//name and salary to be input...
int EMPLOYEE::enter_values()
{ cout<<"Enter name and salary: ";
cin>> name;
cin>>salary;
return 0;
}
//output
int EMPLOYEE::output_values()
{ cout<<"Name: "<<name<<endl;
cout<<"Salary: "<<salary<<endl;
return 0;
}
//
int EMPLOYEE::NEW_SALARY()
{
if ( percentage_raise >= 0)
{ int updated_salary;
int raise= (salary *percentage_raise)/100;
updated_salary += raise;
}
else if(percentage_raise< 0)
{ cout<<"Error Message"<<endl;
}
return 0;
}
int main()
{
EMPLOYEE employees[100];
EMPLOYEE percent_to_be_raised;
int i;
for(i =0 ;i<100 ; i++)
{ employees[i]=EMPLOYEE();
employees[i].enter_values();
employees[i].name;
employees[i].salary;
// employees[i].NEW_SALARY();
employees[i].output_values();
cout<<"How much should the salary be raised by?"<<endl;
cin>>percent_to_be_raised.percentage_raise;
cout<<"-----------------------------"<<endl;
cout<<employees[i].name <<"'s new salary is "<<percent_to_be_raised.updated_salary<<endl;
}
}
You need to rewrite this quite alot.
A few pointers:
EMPLOYEE percent_to_be_raised;
Is completely off base. The task states that this calculation should be done in an employee member function. I.e. the raise should be performed as
Employee alfred;
std::cin>> alfred.salary;
double raise;
std::cin>> raise;
alfred.raise_salary(raise); // this is what the task asks for.
Use a naming convention.
Employee
is fine for a c++ class with a capitalized class name convention. EMPLOYEE is not; this looks like a macro name.
Member function usually starts with non-capitalized
Employee::new_salary( the_salary );
Follow the examples you have available from the course material.
Of course
employees[i].name;
employees[i].salary;
Does not do anything. Please review your code in detail and start at the first spot you don't understand.
Note that the OP coding style convention is used to assist the OP. I am aware of the proper naming convention for classes, member functions, and class data members (e.g. see the answer by Captain Giraffe for more).
Inside of:
int EMPLOYEE::NEW_SALARY()
{
if ( percentage_raise >= 0)
{ int updated_salary;
int raise= (salary *percentage_raise)/100;
updated_salary += raise;
}
} // added this to close the function properly
there is a locally declared variable, which is typed identically to the public access data member of the same name. What is the intention here?
Most likely it should be coded like so:
int EMPLOYEE::NEW_SALARY()
{
if ( percentage_raise >= 0)
{
int raise = (salary *percentage_raise)/100;
updated_salary += raise;
}
} // added this to close the function properly
There are design considerations for having all class member data public, as well as having an integer for a percentage. From the calculation above, it looks like only values of one, two, three, etc. are allowed for the percentage number. What is the class supposed to do if a raise is 3.75 percent?
The constructor has to set ALL class data members to something meaningful too. For example, the percentage_raise and updated_salary variables are ignored. Most likely the default constructor has to be updated to:
//default constructor
EMPLOYEE::EMPLOYEE()
{
name = "";
salary = 0;
percentage_raise = 0;
updated_salary = 0;
}
The name and salary constructor has to be updated too. It should probably look like (using the style convention posted by the OP):
//constructor with name/salary variables
EMPLOYEE::EMPLOYEE(string NAME, int SALARY)
{
name = NAME;
salary = SALARY;
percentage_raise = 0;
updated_salary = salary;
}