C++ Attempting to use a vector - c++

Needing to use a vector for a Film object I have. Having errors thrown at me and unsure as to where things need to be moved to or if I'm naming things wrong. Probably something blatantly obvious.
Code:
#include "std_lib_facilities.h"
int main()
{
class Film
{
public:
Film();
Film(string sl, string el);
};
cout << "Please enter first film:\n";
string start_film;
cin >> start_film;
cout << "\nPlease enter a second film:\n";
string end_film;
cin >> end_film;
cout << "\nPlease enter a date (format = dd/mm/yyyy):\n";
string date;
cin >> date;
string name;
name = "films.txt";
ifstream ist(name.c_str());
if (!ist)
error("Cannot open output file " + name);
vector<Film> temps; // create a vector to store the readings
string film;
string director;
float rating;
int year;
int date;
while (ist >> film >> director >> rating >> year >> date)
{ // read
// check
temps.push_back(Film(film,director, rating, year, date)); // store
}
cout << "Start: " + start_film + " End: " + end_filmn + " Date: " + date + "\n";
keep_window_open();
return 0;
}
Any structure errors that can be pointed out or advice on where to go are much appreciated.
Warnings:
main::Flight::Flight local class member function does not have a body
Error: main::Flight::Flight : No overloaded function takes 5 arguments

Related

How do I access an object out of its block scope?

Hey I am trying to figure out how to access an a object out of the scope of the block. I defined Person personData in the For loop which writes data to the file. And after the loop I wanted to access the object again to update the values on the file but its giving me the error - personData is undefined identifier.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <cstdlib>
#include "Person.h"
using namespace std;
int main() {
string lastName;
string firstName;
int age;
//file output and creation
ofstream outPerson("nameage.dat", ios::out | ios::binary);
Person randPerson;
randPerson.setLastName("unassigned");
randPerson.setFirstName("");
randPerson.setAge(0);
randPerson.setId(0);
//for loop to initialize the file with 100 records that store values lastName and firstName
for (int i = 0; i < 100; i++) {
outPerson.write(reinterpret_cast<const char*>(&randPerson), sizeof(Person)); //use write to output to file
}
cout << "File Created" << endl;
//file input and termination
ifstream inPerson("nameage.dat", ios::in | ios::out | ios::binary);
//loops through 10 times to input 10 values (RECORD VALUES)
for (int j = 0; j < 2; j++) {
int id = 0;
do {
cout << "Enter a valid id number: (1-100)" << endl;
cin >> id;
} while ((id<1)||(id>100)); //breaks do-while after it receives a valid input
Person personData;
inPerson.seekg((id - 1) * sizeof(Person));
inPerson.read(reinterpret_cast<char*>(&personData), sizeof(Person));
//checks to see if there is already data in that area, if not then proceed to record data onto file
if (personData.getId() == 0) {
cout << "Enter lastname: ";
cin >> lastName;
cout << "Enter firstname: ";
cin >> firstName;
cout << "Enter age: ";
cin >> age;
//sets data for the particular object
personData.setLastName(lastName);
personData.setFirstName(firstName);
personData.setAge(age);
personData.setId(id);
//seek position in file of user-specified record
outPerson.seekp((personData.getId() - 1) * sizeof(Person));
//write user-specified information in file
outPerson.write(reinterpret_cast<const char*>(&personData), sizeof(Person));
cout << "Record inserted" << endl;
}
else {
cout << "There is already data there. Try another ID number" << endl;
}//end if
}//end for loop
int idSearch;
do {
cout << "Enter a ID number: " << endl;
cin >> idSearch;
} while ((idSearch < 1) || (idSearch > 100));
if (personData.getId() != 0) {
cout << "Enter new Last name";
cin >> lastName;
cout << "Enter new first name";
cin >> firstName;
cout << "Enter age";
cin >> age;
//sets data for the particular object
personData.setLastName(lastName);
personData.setFirstName(firstName);
personData.setAge(age);
personData.setId(idSearch);
//seek position in file of user-specified record
outPerson.seekp((personData.getId() - 1) * sizeof(Person));
//write user-specified information in file
outPerson.write(reinterpret_cast<const char*>(&personData), sizeof(Person));
cout << "Record updated" << endl;
}
inPerson.read(reinterpret_cast<char*>(&personData), sizeof(Person));
system("pause");
return 0;
}
I'm assuming the problem is because the object cant be accessed when out of scope. So how would I go about accessing the object from the statement below the for loop. Thank you.
It's one of the core ideas of C++ data model: data is deleted as soon, as it leaves the scope.
For this to work, you'd need to change the scope of personData (for example, move variable definition outside of the loop).
But be cautious using something like that. In the very best case personData would store data left by the last iteration of the loop.

User can't put input for second variable. C++

Whenever I run the program, I can only input a value for the first variable, employeeName, but when I hit enter after I input the value, I get a "press any key to continue" prompt. Can somebody please tell me what's wrong?
// Calculate how many hours an employee has worked
#include <iostream>
using namespace std;
int main()
{
//Declare Named Constants
int const HOURS_IN_WORK_WEEK = 40;
int const HOURS_IN_WORK_DAY = 8;
//Declare Variables
int employeeName;
int hoursWorked;
int totalWeeksWorked;
int leftoverFromWeeks;
int totalDaysWorked;
int leftoverFromDays;
int totalHoursWorked;
//Get Input
cout << "enter employee name: ";
cin >> employeeName;
cout << "Enter total hours worked: ";
cin >> hoursWorked;
//calculate total weeks, days, and hours worked
totalWeeksWorked = hoursWorked / HOURS_IN_WORK_WEEK;
leftoverFromWeeks = hoursWorked % HOURS_IN_WORK_WEEK;
totalDaysWorked = leftoverFromWeeks / HOURS_IN_WORK_DAY;
leftoverFromDays = leftoverFromWeeks % HOURS_IN_WORK_DAY;
totalHoursWorked = leftoverFromDays;
//Output
cout << employeeName << "worked " << hoursWorked << "hours or " << totalWeeksWorked << "week(s), " << totalDaysWorked << "day(s), and " << totalHoursWorked << "hours.";
system("pause");
}//End Main
What I presume happened is that you unknowingly entered a string for the employee's name. However, if you look at your declaration:
int employeeName;
The type of the variable is int! Change this to std::string and use getline to read a space separated full name (std::cin will stop reading at whitespace, meaning the rest of the input will be attempted to be stored in an int, leading to the same behavior that happened with the first variable).
The input code would now change to:
cout << "enter employee name: ";
getline(cin, employeeName);
Also, on a side note, you should read why using system("pause") is not a good idea (Although it doesn't really matter for such a small program, it is useful knowledge).

c++ instantiate several classes if a condition is true

Is there a way I can make this work?
I want to create 5 instances of bank if age is greater than 17, but I am getting this error:
[Error] no matching function for call to 'Bank::Bank()'
I need to get this right for my assignment in school.
#include <iostream>
#include <string>
using namespace std;
class Bank{
string Fullname;
string StateOfOrigin;
int Age;
public:
Bank(string name, string state, int age){
Fullname = name;
StateOfOrigin = state;
Age = age;
}
string getname(){
return Fullname;
}
string getstate(){
return StateOfOrigin;
}
int getage(){
return Age;
}
};
int main(){
Bank customer[20];
int x,y,z,age;
string name;
string state;
cout<<"==============================="<<endl;
cout<<"Welcome To Hojma Bank.Plc"<<endl;
cout<<"How many accounts do you want to create? \n";
cin>>y;
for(int k = 0; k < y; k++){
cout<<"Please input your fullname"<<endl;
cin>>name;
cout<<"Please input your state of origin"<<endl;
cin>>state;
cout<<"Please input your age";cout<<endl;
cin>>age;
if(age >= 18){
Bank customer[y](name,state,age);
cout << customer[y].getname();
}
}
}
Bank customer[20];
Here you default-construct twenty Bank objects (oddly called customer??). Or, at least, you tried to, but your Bank class has no default constructor. Neither should it, from what I can tell.
Bank customer[y](name,state,age);
cout << customer[y].getname();
Here I guess you tried to "declare" individual array elements, but it doesn't work like that.
Also your usage of y is wrong; you can accept y maximum, but you probably meant to use the current loop counter value, k. That's broken too because you have a filter on age so you might skip some array elements.
Why not use a nice tasty std::vector, and add new customers at will? Then you can also get rid of those confusing ints, half of which you're not even using.
int main()
{
int y = 0;
cout << "===============================\n";
cout << "Welcome To Hojma Bank.Plc\n";
cout << "How many accounts do you want to create?" << endl;
cin >> y;
std::vector<Bank> customers;
for (int i = 0; i < y; i++) {
int age;
string name;
string state;
cout << "Please input your full name" << endl;
cin >> name;
cout << "Please input your state of origin" << endl;
cin >> state;
cout << "Please input your age" << endl;
cin >> age;
if (age >= 18){
customers.emplace_back(name,state,age);
cout << customer.back().getname();
}
}
}
You could do with some error checking on your user input, too. And rename that class to Customer.
If you create an array of objects (Bank customer[20]), the class needs to have a default constructor. Just define something like this:
Bank() : Fullname(""), StateOfOrigin(""), Age(0) {}

How to read in a set of values from a text file, then go to the next line and do the same

Im trying to read a list like this one
James John 15 5 1
Douglas Frank 23 8 1
Bnejamin Zach 17 1 4
and store each value into a a separate variable. The names are strings, and the other numbers are floats and an int. I can get the data from one line so far, but I dont know how to go onto the next line and do the same. Here is my code so far.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
ifstream employees;
string lastname, firstname, lastname1, firstname1, lastname2, firstname2;
float base, sales, base1, sales1, base2, sales2;
int years, years1, years2;
employees.open("employees.txt");
while (employees)
{
employees >> lastname >> firstname >> base >> sales >> years;
I want to keep it as simple as possible, I dont know user defined functions, arrays, or vectors at all yet. So is there a simple function that will just end the line at years; and go to the next line and carry on?
Thanks.
Use an array. Whenever you end up with "I want to add a number to this variable because I want more than one", if the number reaches more than 2, then you should really use an array (unless very special cases).
You may also want to use a struct to store your different values (firstname, lastname, base, sales and years) - that way, you only get a single array, rather than several different arrays.
Since this is C++, arrays means vector. In other words:
struct employee
{
string firstname, lastname;
float base, sales;
int years;
};
vector<employee> emp_table;
employee e;
while (employees >> e.firstname >> e.lastname >> e.base >> e.sales >> e.years)
{
emp_table.push_back(e);
}
Note I put the input of employees as the while-condition. This avoids an extra loop iteration and "pushing back" a second copy of the last entry when you have reached end of file.
There are many ways in C++ to accomplish what you are trying to do. One approach that allows for data validation is to use the std::getline function to read the file one line at a time and then use a std::stringstream to parse the data.. This allows you to validate the data and continue processing if the data on a line is malformed.
[As Mats noted you can use a data structure and std::vector to make storing and managing the data easier.]
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
struct employee
{
std::string firstname;
std::string lastname;
float base;
float sales;
int years;
};
int main()
{
std::ifstream employeeFile;
employeeFile.open("employees.txt");
std::string tmpLine;
std::vector<employee> employeeTable;
// read in an entire line at a time
while(std::getline(employeeFile, tmpLine))
{
// Place the input line into a stream that reads from
// a string instead of a file.
std::stringstream inputLine(tmpLine);
// Try parsing the data. The ! operator is used here to check
// for errors. Since we expect the data to be in a specific format
// we want to be able to handle situations where the input line
// may be malformed. For example, encountering a string where
// a number should be.
employee e;
if(!(inputLine >> e.firstname >> e.lastname >> e.base >> e.sales >> e.years))
{
// ... error parsing input. Report the error
// or handle it in some other way.
continue; // keep going!
}
// Add to the vector
employeeTable.push_back(e);
}
return 0;
}
You can use getline inside your loop to retrieve each line and then use it with a stringstream
Something like:
string line;
while(getline(employees,line))
{
//doSomething
}
If you can't use arrays to store them easily, you can put a counter to know at which line you're at, but this is very repetitive, and the number of lines in your file cannot vary:
string line;
for (int count = 1 ; count <= 3 ; count++)
{
getline(employees,line);
istringstream iss(line);
if (count == 1)
{
iss >> lastname >> firstname >> base >> sales >> years;
}
else if (count == 2)
{
iss >> lastname1 >> firstname1 >> base1 >> sales1 >> years1;
}
else if (count == 3)
{
iss >> lastname2 >> firstname2 >> base2 >> sales2 >> years2;
}
}
Opening and reading a file properly is harder than learning what an array is. If you don't use an array you have to use too many variables to hold all your data, and you have to repeatedly write the code to read from the file, rather than writing it once in a loop.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string firstNames[3];
string lastNames[3];
float heights[3];
float weights[3];
int ages[3];
ifstream infile("data.txt");
if(!infile)
{
cout << "Couldn't open file!" << endl;
return 1;
}
int count = 0;
while (infile >> firstNames[count]
>> lastNames[count]
>> heights[count]
>> weights[count]
>> ages[count] )
{
++count;
}
infile.close();
for (int i = 0; i<count; ++i) {
cout << firstNames[i] << " "
<< lastNames[i] << " "
<< heights[i] << " "
<< weights[i] << " "
<< ages[i] << " " << endl;
}
return 0;
}
--output:--
James John 15 5 1
Douglas Frank 23 8 1
Bnejamin Zach 17 1 4
Compare to this disaster:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string firstName0,firstName1, firstName2;
string lastName0, lastName1, lastName2;
float height0, height1, height2;
float weight0, weight1, weight2;
int age0, age1, age2;
ifstream infile("data.txt");
if(!infile)
{
cout << "Couldn't open file!" << endl;
return 1;
}
infile >> firstName0 >> lastName0 >> height0 >> weight0 >> age0;
infile >> firstName1 >> lastName1 >> height1 >> weight1 >> age1;
infile >> firstName2 >> lastName2 >> height2 >> weight2 >> age2;
infile.close();
cout << firstName0 << " "
<< lastName0 << " "
<< height0 << " "
<< weight0 << " "
<< age0 << endl;
cout << firstName1 << " "
<< lastName1 << " "
<< height1 << " "
<< weight1 << " "
<< age1 << endl;
cout << firstName2 << " "
<< lastName2 << " "
<< height2 << " "
<< weight2 << " "
<< age2 << endl;
return 0;
}
--output:--
James John 15 5 1
Douglas Frank 23 8 1
Bnejamin Zach 17 1 4
Look at all the code you have to repeat.
Note that when you use an array, the variable names become firstNames[0] (v. firstName0), lastNames[0] (v. lastName0), etc., and firstNames[1] (v. firstName1) and lastNames[1] (v. lastName0).

Taking Input through a string in c++

In C, suppose I need to take input from a string
int num,cost;
char *name[10];
printf("Enter your inputs [quantity item_of_name at cost]");
scanf("%d%*c%s%*c%*s%*c%d",&num,name[0],&cost);
printf("quantity of item: %d",num);
printf("the cost of item is: %d",cost);
printf("the name of item is: %d",name[0]);
INPUT
1 book at 12
OUTPUT
Quantity of item is: 1
The cost of item is: 12
The name of item is: book
Now I want to do the same thing in C++. And I have no idea how to approach. gets() returns the whole string.Is there any specific function that I am missing out on? Please help.
int num,cost;
std::string name;
std::cout << "Enter your inputs [quantity item_of_name at cost]: ";
if (std::cin >> num >> name >> cost)
{ } else
{ /* error */ }
You will want to add errorhandling
In C++ you should rather use cin, cout and string from standard library.
In c++, std::stream provides the read and write communication with the user through the >> operator.
Your code translates to
int num,cost;
std::string name;
std::cout << "Enter your inputs [quantity item_of_name at cost]" << std::flush;
std::cin >> num >> name;
std::cin >> at; // skip the at word
std::cin >> cost;
std::cout << "quantity of item: " << num << std::endl;
std::cout << "the cost of item is: " << cost << std::endl;
std::cout << "the name of item is: " << name << std::endl;
You could use iostream's cin.
int num,cost;
char *name[10];
std::cout <<"Enter your quantity"<<std::endl;
std::cin>> num;
std::cout<<" Enter the cost"<<std::endl;
std::cin>>cost;
std::cout<<"Enter the name"<<std::endl;
std::cout<<"The quantity of the item is: "<<num<<" costing: "<<cost<<" for "<<name[0]<<std::endl;
and then of course you could also use std::string instead of char*.
Or streamline the cin's as cin >> num >> cost >> name;
Also, as Griwes noted, you will want to perform error checking on your results.