C++ getting ofstream access error when passed to a function - c++

For some reason the ofstream out with the iterator at the bottom is denying access to itself for some reason, something having to do with the pointer? Honestly, me and my friends have been trying to figure out what is wrong here for a long time. Even a veteran who has been coding for years couldn't help me. Any help is appreciated! here is the error:
Error 6 error C2248: 'std::basic_ofstream<_Elem,_Traits>::basic_ofstream' : cannot access private member declared in class 'std::basic_ofstream<_Elem,_Traits>'
as well as intellisense
7 IntelliSense: "std::basic_ofstream<_Elem, _Traits>::basic_ofstream(const std::basic_ofstream<_Elem, _Traits>::_Myt &_Right) [with _Elem=char, _Traits=std::char_traits]" (declared at line 1034 of "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\fstream") is inaccessible
/*
estimate.cc -- Program to estimate the cost of attendance for students -- Part 1
This part will read the records, place them in separate vectors, sort them,
and then write them out to separate files.
Authors: Larry Morell,
Aaron Wilson
Strategy:
Create a class for a general student called Student
Divide students into three categories: Resident, Commuter, Onliner.
Set up a class for each one of these categories to inherit from Student.
The input file is called students.dat. Its format is as follows.
HourlyRate Fees CentsPerMile -- first line
The remaining lines are one of three formats, one line for each student
R FirstName LastName GPA HoursRegistered Major MealPlan Housing -- for resident student
C FirstName LastName GPA HoursRegistered Major Miles MealPlan -- for commuter student
O FirstName LastName GPA HoursRegistered Major ISP_Cost -- for onliner student
Modification History
Date Action
10/30/15 -- Original version
11/18/15 -- vectors program
12/1/15 -- polymorphism, changing it to use only one vector and pointers
*/
using namespace std;
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>
#include <algorithm>
class Student {
protected:
string first, last; // First and laast name
float gpa; // Grade point average
int hoursRegistered; // Number of hours registered for next semester
string major; // Declared major or "Undeclared
static float hourlyRate; // What the college charges per credit hour
static float fees; // The flat fees charged to each student
static float costPerMile; // Cost per mile for travel
public:
// Constructors
Student() {
first = "Unknown";
last = "Person";
gpa = 0.0;
hoursRegistered = 0;
}
Student(string fn, string ln, float gpa, int hours ) {
this->first = fn;
this->last = ln;
this->gpa = gpa;
this->hoursRegistered = hours;
}
// Setters
static void setHourlyRate(float hr) { hourlyRate = hr; }
static void setFees(float f) { fees = f; }
static void setCostPerMile(float cpm) { costPerMile = cpm; }
// Getters
string getMajor() const { return major; }
string getName() const { return first + ' ' + last; }
string getFirst() const { return first; }
string getLast() const { return last; }
int getHoursRegistered() const { return hoursRegistered; }
float getBookCost() const { return 30.00*hoursRegistered ;}
// Input routine
bool read(istream &in) {
in >> first >> last >> gpa >> hoursRegistered >> major;
return in;
}
// Output routine
void write (ostream &out) {
out << first << ' ' << last << ' '
<< gpa << ' ' << hoursRegistered
<< ' ' << major;
}
// estimate -- determine the cost of attending next semester
virtual void estimate(ofstream thisOut)
{
}
};
// Declare location of static variables as globals as required by C++
// These are variables that are shared by all instances of class Student
// and its descendants
float Student::hourlyRate;
float Student::fees;
float Student::costPerMile;
// Class Resident -- extends Student
class Resident : public Student {
protected:
float mealPlan;
float housing;
public:
bool read(istream &in) {
Student::read(in);
in >> mealPlan >> housing;
return in;
}
void write (ostream &out) {
Student::write(out); // Call the write routine inherited from Student
out << ' ' << mealPlan << ' ' << housing;
}
virtual void estimate(ofstream thisOut) {
thisOut << "Dear " + first + ' ' + last + ',' << endl << endl << "You are registered for " << hoursRegistered << " hours. Your costs for the upcoming year have been calculated as follows:" << endl;
thisOut << "Tuition: " << fixed << '$' << (hoursRegistered * hourlyRate) << endl;
thisOut << (hoursRegistered * hourlyRate) + fees + mealPlan + housing;
}
};
// Class Commuter -- extends Student
class Commuter : public Student {
private:
// Must contain miles , mealplan
float miles;
float mealplan;
public:
bool read(istream &in) {
Student::read(in);
in >> mealplan >> miles;
return in;
}
void write (ostream &out) {
Student::write(out);
out << ' ' << mealplan << ' ' << miles;
}
virtual void estimate(ofstream thisOut) {
thisOut << "Dear " + first + ' ' + last + ',' << endl << endl << "You are registered for " << hoursRegistered << " hours. Your costs for the upcoming year have been calculated as follows:" << endl;
thisOut << "Tuition: " << fixed << '$' << (hoursRegistered * hourlyRate) << endl;
thisOut << (hoursRegistered * hourlyRate) + (miles * costPerMile) + fees + mealplan;
}
};
// Class Onliner -- extends Student
class Onliner : public Student {
private:
// Must contain ispcost
float ispcost;
public:
bool read(istream &in) {
Student::read(in);
in >> ispcost;
return in;
}
void write (ostream &out) {
Student::write(out);
out << ispcost;
}
virtual void estimate(ofstream thisOut)
{
thisOut << "Dear " + first + ' ' + last + ',' << endl << endl << "You are registered for " << hoursRegistered << " hours. Your costs for the upcoming year have been calculated as follows:" << endl;
thisOut << "Tuition: " << fixed << '$' << (hoursRegistered * hourlyRate) << endl;
thisOut << (hoursRegistered * hourlyRate) + fees + ispcost;
}
};
// compareStudents -- returns whether or not s1 is less than s2
bool compareStudents(Student* s1, Student* s2) {
return s1 -> getLast() < s2 -> getLast();
}
int main () {
// Declare locals for holding input
ifstream in ("students.dat");
float hourlyRate, fees, costPerMile;
// Read and store the hourly rate, fees and cost per mile
in >> hourlyRate >> fees >> costPerMile;
Student::setHourlyRate(hourlyRate);
Student::setFees(fees);
Student::setCostPerMile(costPerMile);
// Read student records from the input file
char studentType;
vector <Student *> studentVector;
while (in >> studentType) {
if (studentType == 'R') {
Resident *r = new Resident;
r -> read(in);
studentVector.push_back(r);
}
else if(studentType == 'C') {
Commuter *c = new Commuter;
c->read(in);
studentVector.push_back(c);
}
else if(studentType == 'O') {
Onliner *o = new Onliner;
o->read(in);
studentVector.push_back(o);
}
else { // These two lines will need to be replaced
cout << "error: data in file is not correct" << endl;
}
}
// Sort the entire resident list using the supplied comparison routine
sort(studentVector.begin(), studentVector.end(), compareStudents);
// Write the vectors to their respective files
ofstream out;
out.open("students.dat");
for (auto ptr: studentVector) {
ptr -> estimate(out);
}
out.close();
return 0;
}

You're passing the stream by value into the function, but streams cannot be copied.
Define the function as
virtual void estimate(ofstream& thisOut)
instead.
There are also a few places where you need to replace return in with return in.good() (or static_cast<bool>(in)) for compatibility with C++11 and later.

Related

How to input an object in C++?

Hi the code below is a simple class example in C++
#include <iostream>
using namespace std;
class Car { // The class
public: // Access specifier
string brand; // Attribute
string model; // Attribute
int year; // Attribute
Car(string x, string y, int z) { // Constructor with parameters
brand = x;
model = y;
year = z;
}
};
int main() {
// Create Car objects and call the constructor with different values
Car carObj1("BMW", "X5", 1999);
Car carObj2("Ford", "Mustang", 1969);
// Print values
cout << carObj1.brand << " " << carObj1.model << " " << carObj1.year << "\n";
cout << carObj2.brand << " " << carObj2.model << " " << carObj2.year << "\n";
return 0;
}
// W3Schools
As I see it, the way you can define an object is to write it in code like : <ClassName> <ObjectName>
Now my question is : Is there a way to input an object? like cin >> ObjectName;
And after we entered the name of object, we enter the parameters.
Is it possible at all?
You can't enter an object name from the command line, however, you can create a default constructed object and then fill its' properties from the input by overloading operator>>.
class Car {
public:
Car() = default;
// ...
};
std::istream& operator>>(std::istream& in, Car& car) {
in >> car.brand >> car.model >> car.year;
return in;
}
int main() {
Car carObj1;
cout << "Enter a car brand, model, and year: ";
cin >> carObj1;
// ...
}
Yes, There is operator overloading in C++ and you can overload both << and >> operators. Here is an example code:
#include <iostream>
using namespace std;
class Car { // The class
public: // Access specifier
string brand; // Attribute
string model; // Attribute
int year; // Attribute
Car(string x, string y, int z) { // Constructor with parameters
brand = x;
model = y;
year = z;
}
Car() = default;
void Carinput(std::istream& is)
{
is >> brand >> model >> year;
}
void carOutput(std::ostream& os) const
{
os << brand << " " << model << " " << year << std::endl;
}
};
std::istream &operator>>(std::istream &is,Car &car)
{
car.Carinput(is);
return is;
}
std::ostream &operator<<(std::ostream &os,const Car &car)
{
car.carOutput(os);
return os;
}
int main() {
// Create Car objects and call the constructor with different values
Car carObj1("BMW", "X5", 1999);
Car carObj2("Ford", "Mustang", 1969);
// Print values
cout << carObj1.brand << " " << carObj1.model << " " << carObj1.year << "\n";
cout << carObj2.brand << " " << carObj2.model << " " << carObj2.year << "\n";
std::cout << "\n*============================================*\n"
<< std::endl;
std::cout << "Your input:" << std::endl;
Car carObj3;
std::cin >> carObj3;
std::cout << carObj3;
return 0;
}
This is one of the ways of doing it:
#include<iostream>
#include<vector>
class Car
{
public:
Car( const std::string& brand, const std::string& model, int year )
: m_brand( brand ), m_model( model ), m_year( year ) // initialize members like this
{
}
std::string m_brand;
std::string m_model;
int m_year;
};
int main ()
{
std::vector< Car > cars; // use an std::vector to store the objects
std::string brand( "" );
std::string model( "" );
std::string year( "" );
std::cout << "How many cars do you want to add? ";
std::string count( "" );
std::getline( std::cin, count ); // get input as string using std::getline()
int carCount { std::stoi( count ) }; // converts it to type int before
// assigning it to carCount
cars.reserve( carCount ); // reserve some space in vector to avoid
// unnecessary allocations and slowdowns
for ( int idx = 0; idx < carCount; ++idx )
{
std::cout << "Enter the brand name of car number " << idx + 1 << ": ";
std::getline( std::cin, brand );
std::cout << "Enter the model name of car number " << idx + 1 << ": ";
std::getline( std::cin, model );
std::cout << "Enter the production year of car number " << idx + 1 << ": ";
std::getline( std::cin, year );
cars.emplace_back( Car( brand, model, std::stoi( year ) ) ); // push the new Car
} // instance to the
// vector called cars
std::cout << '\n';
for ( int idx = 0; idx < carCount; ++idx )
{
std::cout << "Info for car number " << idx + 1 << ": "
<< cars[ idx ].m_brand << " " << cars[ idx ].m_model << " " << cars[ idx ].m_year << "\n";
}
return 0;
}
Here is the output:
How many cars do you want to add? 2
Enter the brand name of car number 1: Porsche
Enter the model name of car number 1: GT3 RS
Enter the production year of car number 1: 2019
Enter the brand name of car number 2: BMW
Enter the model name of car number 2: M6
Enter the production year of car number 2: 2016
Info for car number 1: Porsche GT3 RS 2019
Info for car number 2: BMW M6 2016
But keep in mind that this class still needs a lot of work like adding member functions (like getters and setters) etc. So this is not how I write classes. I just wanted to keep it simple so you can easily understand the concepts.

The code compiles it does not read staff.txt

The code compiles it does not read staff.txt. Not sure how to fix in the code. the error must be in reading the staff.txt of the code. Does anyone have an idea? output is in the image provided. Background on the question:
You are tasked to create 2 ADTs: customers and staff. Each customer will have a first and last name, an indication if the customer is enrolled in the “preferred” program, the car they are driving, and the amount of money owed to the company. On the other hand, each staff member will have a first and last name, the car they are driving, and their salary. In a real-world problem, there would obviously be more records associated with each staff member and customer.
ODU rentals would like you to automatically process txt files and print the information to the console screen. When you perform this process, ensure that your member variables are private. In addition, be sure to use getter and setter functions to manipulate and print your data. You may print your data in any format as long as it is organized. An example of correct output can be seen below.
#include <iostream>
#include <fstream>
#include <iomanip>
#include <string>
#include <cstdlib>
using namespace std;
class Customer {
string fname;
string lname;
int enroll;
string car;
float amount;
public:
//Defining the customer ADT
Customer();
void setFirstName(string fnm);
void setLastName(string lnm);
void setEnroll(int e);
void setCarName(string cnm);
void setAmount(float amt);
string getFirstName();
string getLastName();
int getEnroll();
string getCarName();
float getAmount();
void printData();
};
Customer::Customer() {
fname = lname = car = "";
enroll = 0;
amount = 0;
}
void Customer::setFirstName(string fnm) {
fname = fnm;
}
void Customer::setLastName(string lnm) {
lname = lnm;
}
void Customer::setEnroll(int e) {
enroll = e;
}
void Customer::setCarName(string cnm) {
car = cnm;
}
void Customer::setAmount(float amt) {
amount = amt;
}
string Customer::getFirstName() {
return(fname);
}
string Customer::getLastName() {
return(lname);
}
int Customer::getEnroll() {
return(enroll);
}
string Customer::getCarName() {
return(car);
}
float Customer::getAmount() {
return(amount);
}
void Customer:: printData() {
cout << left << setw(25) << getFirstName()+" "+getLastName() << left <<setw(15) << getEnroll();
cout << left << setw(15) << getCarName() << left << setw(15) << fixed << setprecision(2) << getAmount() << endl;
}
class Staff {
string fname;
string lname;
string car;
float salary;
public:
//Defining staff ADT
Staff();
void setFirstName(string fnm);
void setLastName(string lnm);
void setCarName(string cnm);
void setSalary(float sal);
string getFirstName();
string getLastName();
string getCarName();
float getSalary();
void printData();
};
Staff::Staff() {
fname = lname = car = "";
salary = 0;
}
void Staff::setFirstName(string fnm) {
fname = fnm;
}
void Staff:: setLastName(string lnm) {
lname = lnm;
}
void Staff::setCarName(string cnm) {
car = cnm;
}
void Staff::setSalary(float sal) {
salary = sal;
}
string Staff::getFirstName() {
return(fname);
}
string Staff::getLastName() {
return(lname);
}
string Staff::getCarName() {
return(car);
}
float Staff::getSalary() {
return(salary);
}
void Staff:: printData() {
cout << left << setw(25) << getFirstName()+" "+getLastName() << left << setw(15);
cout << getCarName() << left << setw(15) << fixed << setprecision(2) << getSalary() <<endl;
}
//Main function
//Read txt files
int main() {
string fnm, lnm, carnm;
float amt, sal;
int e, i=0, recno;
ifstream fstaff("staff.txt");
if(!fstaff) {
cout << "File can not be opened" << endl;
exit(1);
}
fstaff >> recno;
Staff s[recno];
cout << left<<setw(25) << "Name" << left << setw(15) << "Car" << left << setw(15) << "Salary" <<endl;
cout << "____________________________________________________________________________" << endl;
for(i=0; i<recno; i++) {
fstaff>>fnm>>lnm>>carnm>>sal;
s[i].setFirstName(fnm);
s[i].setLastName(lnm);
s[i].setCarName(carnm);
s[i].setSalary(sal);
s[i].printData();
}
fstaff.close();
ifstream fcust("customers.txt");
if(!fcust) {
cout << "File can not be opened"<<endl;
exit(1);
}
fcust >> recno;
Customer c[recno];
cout << endl << endl;
cout << left << setw(25) << "Name" << left << setw(15) << "Preferred" << left << setw(15) << "Car" << left << setw(15) << "Bill" << endl;
cout <<"____________________________________________________________________________"<<endl;
for(i=0; i<recno; i++) {
fcust >> fnm >> lnm >> e >> carnm >>amt;
c[i].setFirstName(fnm);
c[i].setLastName(lnm);
c[i].setEnroll(e);
c[i].setCarName(carnm);
c[i].setAmount(amt);
c[i].printData();
}
fcust.close();
return 1;
}
Code Output

Unable to populate array of structures

my program is supposed to parse through strings from a file and store in the array of structs.
Example: Skyfall, 1.109, Sam Mendes, 11/9/12, 143. Program will parse the string and store the title, gross, director name etc.
Whenever i run the code it doesn't seem to store it properly.
Also, I'm getting this error.
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
Here's my struct:
struct Movie
{
string Title; // Movie title
string Gross; // Gross total in billion dollars
string Director; // Director name
string Date; // Release date
string Runtime; // Runtime in minutes
};
This function is to create the array of objects and open the file
Movie* createDatabase(int& number_Of_Lines)
{
// input file
ifstream movie_file;
string filename;
do
{
cout << "Please enter filename: " ;
getline (cin , filename);
movie_file.open(filename.c_str());
if(movie_file.fail())
cout << "Invalid file" << endl ;
}while(movie_file.fail());
// array of objects
number_Of_Lines = numberOfLines(movie_file);
Movie* ptr = new Movie [number_Of_Lines];
//Looping through array of objects
for(int i = 0 ; i < number_Of_Lines ; i++)
populateMovieFromFile(movie_file, ptr[i]);
return ptr;
}
This function populates the objects
void populateMovieFromFile(ifstream& movie_file, Movie& movies)
{
getline(movie_file, movies.Title, ',');
movie_file.ignore();
getline(movie_file, movies.Gross, ',');
movie_file.ignore();
getline(movie_file, movies.Director, ',');
movie_file.ignore();
getline(movie_file, movies.Date, ',');
movie_file.ignore();
getline(movie_file, movies.Runtime);
}
Full program:
#include <iostream>
#include <string>
#include <fstream>
#include <iomanip>
#include <cctype>
using namespace std;
struct Movie
{
string Title; // Movie title
string Gross; // Gross total in billion dollars
string Director; // Director name
string Date; // Release date
string Runtime; // Runtime in minutes
};
int numberOfLines(ifstream&);
void populateMovieFromFile(ifstream&, Movie&);
void displayMovie(const Movie&);
Movie* createDatabase(int&);
bool caseInsensitiveCmp(string, string);
void findMovie(Movie*, int);
void saveToFile(const Movie&);
bool promptToContinue();
//void displayFavorites();
int main ()
{
int number_Of_Lines = 0;
Movie* ptr_movies = createDatabase(number_Of_Lines);
do
{
findMovie(ptr_movies , number_Of_Lines);
}while (!promptToContinue());
//displayFavorites();
return 0;
}
int numberOfLines(ifstream& movie_file)
{
int number_Of_Lines = 0;
string lines;
if(movie_file)
{
while(getline(movie_file, lines))
number_Of_Lines++ ;
}
movie_file.seekg (0, ios::beg);
return number_Of_Lines;
}
void populateMovieFromFile(ifstream& movie_file, Movie& movies)
{
getline(movie_file, movies.Title, ',');
movie_file.ignore();
getline(movie_file, movies.Gross, ',');
movie_file.ignore();
getline(movie_file, movies.Director, ',');
movie_file.ignore();
getline(movie_file, movies.Date, ',');
movie_file.ignore();
getline(movie_file, movies.Runtime);
}
void displayMovie(const Movie& movie)
{
cout << right << setw(13) << "Title: " << left << movie.Title << endl;
cout << right << setw(13) << "Gross Total: " << left << movie.Gross << " billion dollars" << endl;
cout << right << setw(13) << "Director: " << left << movie.Director << endl;
cout << right << setw(13) << "Release date: " << left << movie.Date << endl;
cout << right << setw(13) << "Runtime: " << left << movie.Runtime << " minutes" << endl;
}
Movie* createDatabase(int& number_Of_Lines)
{
// input file
ifstream movie_file;
string filename;
do
{
cout << "Please enter filename: " ;
getline (cin , filename);
movie_file.open(filename.c_str());
if(movie_file.fail())
cout << "Invalid file" << endl ;
}while(movie_file.fail());
// array of objects
number_Of_Lines = numberOfLines(movie_file);
Movie* ptr = new Movie [number_Of_Lines];
//Looping through array of objects
for(int i = 0 ; i < number_Of_Lines ; i++)
populateMovieFromFile(movie_file, ptr[i]);
return ptr;
}
bool caseInsensitiveCmp(string input, string list) //list will be from the object of array
{
int i = 0 , j = 0;
while (input[i])
{
char c = input[i];
input[i] = tolower(c);
i++;
}
while (list[j])
{
char c = list[j];
list[j] = tolower(c);
j++;
}
if (input == list)
return true;
else
return false;
}
void findMovie(Movie* ptr_movie, int number_Of_Lines)
{
cout << endl;
int i = 0;
char save;
string input_title;
bool found = false;
bool No_Match = false;
cout << "Enter a movie title to search for: ";
getline(cin , input_title);
do
{
found = caseInsensitiveCmp(ptr_movie[i].Title , input_title); //loop it
if (found == false)
i++;
if (i>=number_Of_Lines)
No_Match = true;
} while (found == false || No_Match == false);
if(found == true)
{
displayMovie(ptr_movie[i]);
cout << endl ;
cout << "Would you like to save the above movie? (Y or N)" << endl;
cin >> save;
if (save == 'y' || save == 'Y')
saveToFile(ptr_movie[i]);
}
else
cout << input_title << " not found in database. Please try again." << endl;
}
void saveToFile(const Movie& movie)
{
ofstream outfile;
outfile.open("favourites.txt", ios::app);
cout << movie.Title << "," << movie.Gross << ","
<< movie.Director << "," << movie.Date << ","
<< movie.Runtime << endl;
}
bool promptToContinue()
{
char Quit;
bool exit = false;
cout << "Would you like to exit? (Y or N): ";
cin >> Quit;
switch (Quit)
{
case 'Y':
case 'y':
exit = true;
case 'N':
case 'n':
exit = false;
}
return exit;
}
Any help is appreciated
The problem is:
In your "saveToFile" function, you open a ofstream, but do not use it. Instead you write to std::cout. So, you do not store the data.
Additionally, you are calling new but never delete. With that you are creating a memory leak.
Then, you still thinking to much in C. You should not use new or plain C-Style arrays. Never.
You should instead use STL containers and a more object oriented approach. At the moment you are using a lot of global functions, working with data.
In C++ you should use objects and associated data and methods. For example, a Movie knows how to read and store its data. Therefore implement that as a method.
And a Movie database is an additional object that contains a vector of movies.
To give you an idea of a more object oriented approach, I create a small example for you.
Please see and try to understand.
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <regex>
#include <string>
class Movie
{
public:
// Overload Extractor Operator to read data from somewhere
friend std::istream& operator >> (std::istream& is, Movie& m);
// Overload Inserter operator. Insert data into output stream
friend std::ostream& operator << (std::ostream& os, const Movie& m);
// Show movie data on std::out
void display() const;
// Check if a movie has a certain title
bool hasTitle(const std::string& t) const { return t == title; }
private:
// Data
std::string title{}; // Movie title
std::string gross{}; // Gross total in billion dollars
std::string director{}; // Director name
std::string date{}; // Release date
std::string runtime{}; // Runtime in minutes
};
// Overload Extractor Operator to read data from somewhere
std::istream& operator >> (std::istream& is, Movie& m) {
std::vector<std::string> dataInOneLine{}; // Here we will store all data that we read in one line;
std::string wholeLine; // Temporary storage for the complete line that we will get by getline
std::regex separator(","); ; // Separator for a CSV file
std::getline(is, wholeLine); // Read one complete line
// Parse the line and split it into parts
std::copy(std::sregex_token_iterator(wholeLine.begin(), wholeLine.end(), separator, -1),
std::sregex_token_iterator(),
std::back_inserter(dataInOneLine));
// If we have read all expted strings, then store them in our struct
if (dataInOneLine.size() == 5) {
m.title = dataInOneLine[0];
m.gross = dataInOneLine[1];
m.director = dataInOneLine[2];
m.date = dataInOneLine[3];
m.runtime = dataInOneLine[4];
}
return is;
}
std::ostream& operator << (std::ostream& os, const Movie& m) {
// Copy csv data to ostream
return os << m.title << "," << m.gross << "," << m.director << "," << m.date << "," << m.runtime << "\n";
}
void Movie::display() const {
std::cout << " Title: " << title << "\n Gross Total: " << gross << " billion dollars\n Director: " << director
<< "\nRelease date: " << date << "\n Runtime: " << runtime << " minutes\n";
}
// Database for Movies
class MovieDatabase {
public:
// Constructor. Open and read the database
explicit MovieDatabase(const std::string pafn) : pathAndFileName(pafn) { open(); }
// Destructor automatically saves and closes the database
~MovieDatabase() { close(); };
// Open/close the database
bool open();
void close();
// Add a new movie
void addMovie(const Movie& m) { data.push_back(m); }
// Find and display a movie
bool findAndDisplay (const std::string& title);
private:
const std::string pathAndFileName{};
std::vector<Movie> data{};
};
// Destructor
void MovieDatabase::close() {
// Save data
std::ofstream outFileStream{ pathAndFileName, std::ios::trunc };
if (outFileStream) {
// then save all data in csv format
std::copy(data.begin(), data.end(), std::ostream_iterator<Movie>(outFileStream));
}
}
// Open database and read the data from disk
bool MovieDatabase::open() {
bool success{ false };
// Open the file
std::ifstream inFileStream{ pathAndFileName };
// If the file could be opened
if (inFileStream) {
success = true;
// Then copy all data from disk, parse the csv and store it in our data vector
std::copy(std::istream_iterator<Movie>(inFileStream), std::istream_iterator<Movie>(), std::back_inserter(data));
}
return success;
}
// Find and display a value
bool MovieDatabase::findAndDisplay (const std::string& title) {
bool found { false };
// Search for a given title
std::vector<Movie>::iterator md = std::find_if(data.begin(), data.end(), [&title](const Movie &m) { return m.hasTitle(title); });
if (data.end() != md) {
// If found, then display it
md->display();
found = true;
}
else {
std::cerr << "\n\nTitle '" << title << "' not found in database\n\n";
}
return found;
}
int main() {
// Get the name of the database
std::string pathNameDatabase{};
std::cout << "Enter the path/filename of the database:\n";
std::cin >> pathNameDatabase;
// Define database and open it
MovieDatabase md{ pathNameDatabase };
// Do some stuff
std::cout << "\n\nSearch for title. Please enter title:\n";
std::string title{};
std::cin >> title; std::cin.ignore();
// Search and display data
md.findAndDisplay(title);
// Add a new record
std::cout << "\n\nAdd new movie data\nPlease enter title, gross, director, date, runtime (in one line, seperated by comma):\n";
Movie m{};
std::cin >> m;
m.display();
md.addMovie(m);
return 0;
}

How to debug "ISO C++ forbids declaration of 'car' with no type"?

I am trying to figure out why I keep getting this error on Dev C++. I don't seem to get any errors when I use computers from my school, so I was wondering if I have missed something here.
[Error] ISO C++ forbids declaration of 'car' with no type -f
permissive
Code:
#include <iostream>
#include <string>
using namespace std;
class Car //class definition
{
private: int modelYr; string model; int speed;
public:
car(int year, string brand)
{ modelYr=year; model=brand; speed=0;} //Constructor
void accelerate() {speed = speed + 5;} //accelerate +5mph (mutator)
void brake() {speed = speed - 5;} //brake -5mph (mutator)
int get_modelYr() const {return modelYr;} //returns model year (accessor)
string get_model() const {return model;} //returns model name (accessor)
int getspeed() const {return speed;} //returns current speed (accessor)
};//end of class definition (note the semicolon ;)
int main() {
Car vehicle; //create a vehicle from class Car
string carModel;//car model to be input by user
int carYear; //car year to be input by user
const string line = "\n-------------------\n"; //used to display a line
cout <<"Enter car model year (2000-current): ";
while(! (cin >> carYear) || (carYear < 2000) ) //carYear validation
{ //checking for numeric year 2000 or later
cin.clear();cin.ignore(10000,'\n');
cout<<"sorry you must enter car year 2000 or later :"<<flush;
} //while loop validation ends
cout <<"Enter car model (example: GMC): "; cin >> carModel;
vehicle.car(carYear,carModel);
cout << line << "Starting speed for your " << vehicle.get_modelYr()
<< " " << vehicle.get_model() << " is " << vehicle.getspeed() << " mph" <<line;
for(int count=0;count<5;count++) //accelerate five times
{ vehicle.accelerate();
cout << "***ACCELERATING***\nSpeed is currently:"<< vehicle.getspeed() << endl;
}//end acceleration
for ( int count=0;count<5 ;count++ )
{vehicle.brake();
cout << "***BRAKING***\nSpeed is currently: " << vehicle.getspeed() << endl;
}
cout << line << "Ending speed for your " << vehicle.get_modelYr()
<< " " << vehicle.get_model() << " is " << vehicle.getspeed() <<" mph"<< line;
return(0);
}//end of main program
Your constructor must be named the same as your class.
#include <iostream>
#include <string>
using namespace std;
class Car //class definition
{
private: int modelYr; string model; int speed;
public:
Car(int year, string brand)
{ modelYr=year; model=brand; speed=0;} //Constructor
void accelerate() {speed = speed + 5;} //accelerate +5mph (mutator)
void brake() {speed = speed - 5;} //brake -5mph (mutator)
int get_modelYr() const {return modelYr;} //returns model year (accessor)
string get_model() const {return model;} //returns model name (accessor)
int getspeed() const {return speed;} //returns current speed (accessor)
};//end of class definition (note the semicolon ;)
int main() {
Car vehicle; //create a vehicle from class Car
string carModel;//car model to be input by user
int carYear; //car year to be input by user
const string line = "\n-------------------\n"; //used to display a line
cout <<"Enter car model year (2000-current): ";
while(! (cin >> carYear) || (carYear < 2000) ) //carYear validation
{ //checking for numeric year 2000 or later
cin.clear();cin.ignore(10000,'\n');
cout<<"sorry you must enter car year 2000 or later :"<<flush;
} //while loop validation ends
cout <<"Enter car model (example: GMC): "; cin >> carModel;
vehicle.car(carYear,carModel);
cout << line << "Starting speed for your " << vehicle.get_modelYr()
<< " " << vehicle.get_model() << " is " << vehicle.getspeed() << " mph" <<line;
for(int count=0;count<5;count++) //accelerate five times
{ vehicle.accelerate();
cout << "***ACCELERATING***\nSpeed is currently:"<< vehicle.getspeed() << endl;
}//end acceleration
for ( int count=0;count<5 ;count++ )
{vehicle.brake();
cout << "***BRAKING***\nSpeed is currently: " << vehicle.getspeed() << endl;
}
cout << line << "Ending speed for your " << vehicle.get_modelYr()
<< " " << vehicle.get_model() << " is " << vehicle.getspeed() <<" mph"<< line;
return(0);
}//end of main program

Trying to sort Vector of Objects

As the title suggest, I am trying to sort a vector of objects by the GPA. My main issue is putting a method where I define the function for my comparison. The vector itself holds objects of five fields, which includes: string name, string ssn, string year, float credit, float gpa. I know theirs a way to use the sort operator. I am new to C++ so I am not very knowledgeable in this language. I appreciate the help! Here is the code:
#include <iostream>
#include <string>
#include <iterator>
#include <iomanip>
#include <fstream>
#include <vector>
#include <sstream>
#include <algorithm>
#include <cstdlib>
#include <list>
using namespace std;
class Student {
//declare local variables
protected:
string name; //people with names longer than 21 characters will just
have to make do
string ssn; // Social Secturity Number.
float gpa; //Most up to date gpa for the student
float credits; //Number of student's credit hours
//build public methods
public:
//Default Constructor
Student() {}
//Student constructor. Besides the character arrays, everything else is passed by reference.
Student(const string n, const string s, string sGPA, string sCredits) {
name = n;
ssn = s;
gpa = (float)atof(sGPA.c_str());
credits = (float)atof(sCredits.c_str());
}
string getName() {
return name;
}
string getSSN() {
return ssn;
}
float getGPA() {
return gpa;
}
float getCredit() {
return credits;
}
//a function that is expected to be implemented and overridden by subclasses
virtual void print() const {
cout << '\n' << endl;
cout << "Student's name: " << name << endl;
cout << "Student SSN: " << ssn << endl;
cout << "Student's current GPA: " << gpa << endl;
cout << "Student's credit hours: " << credits << endl;
}
// a pure virtual function for implementation later. Makes whole class Abstract
virtual float tuition() const = 0;
};
class Undergrad : public Student {
//declare local variables
protected:
float undergrad_rate = 380.0;
string year;
//build public methods
public:
//Default Constructor
Undergrad() {}
//Undergrad Constructor
Undergrad(const string n, const string s, string uGPA, string uCredits, string y) :
Student(n, s, uGPA, uCredits), year(y) {}
//Display the contents of undergrad
void print() const {
Student::print();
cout << "Undergrad Rate: " << undergrad_rate << endl;
cout << "Year: " << year << endl;
}
//Display undergrad's current year
string get_year() {
return year;
}
//Display the undergrad's current rate
float get_rate() {
return undergrad_rate;
}
//Set a undergrad's current year
void set_year(string y) {
year = y;
}
//Display the cost for an undergrad to attend university
float tuition() const {
return 1000000;
}
};
int main() {
ifstream ip("data.txt");
if (!ip.is_open()) std::cout << "ERROR: File not found" << '/n';
string name;
string ssn;
string year;
string credit;
string gpa;
list<Undergrad> myList;
list<Undergrad>::iterator i;
//Undergrad g(name, ssn, year, credit, gpa);
while (ip.good()) {
getline(ip, name, ',');
getline(ip, ssn, ',');
getline(ip, gpa, ',');
getline(ip, credit, ',');
getline(ip, year, '\n');
// float number = stoi(gpa);
//float number1 = stoi(credit);
Undergrad g(name, ssn, year, credit, gpa);
myList.push_back(g);
}
ip.close();
//This deletes the last object in the list and stores it in a temp object. It assigns that object to the beginning of the list.
Undergrad temp = myList.back();
myList.pop_back();
myList.insert(myList.begin(), temp);
/* for (int i = 0; i < myList.size(); i++) {
cout << "Name: " << myList[i].getName() << endl;
cout << "SSN: " << myList[i].getSSN() << endl;
cout << "Year: " << file[i].get_year() << endl;
cout << "Credit: " << file[i].getCredit() << endl;
cout << "GPA " << file[i].getGPA() << endl;
cout << " " << endl;
}
*/
/*for (Undergrad &x : myList) { //Goes through my list and displays its contents
x.print(); //This isn't bringing up errors.
}
*/
//This code copy the contents of the list to a vector.
std::vector<Undergrad> vect{ std::make_move_iterator(std::begin(myList)),
std::make_move_iterator(std::end(myList)) };
std::sort(vect.begin(), vect.end(), CompareGPA);
for (Undergrad &x : vect) {
x.print();
}
system("pause");
return 0;
}
Furthermore this is the code Im trying to implement to get the comparision
bool CompareGPA(const Student& left, const Student& right) {
return left.gpa > right.gpa;
}
Using lambda you can implement like this:Use a property int get_gpa() const to access the protected member.
std::sort(vect.begin(), vect.end(), [] (const Student& left, const Student& right)
{
return left.get_gpa() > right.get_gpa();
});
Here how to implement the property ( a member function to return the protected variable) :
int get_gpa() const
{
return gpa;
}