Sorting a private element of a class [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
how to sort an integer that is declared in the private
I am having trouble on how to sort the int id element in the class,
here is where i would put my functions for the class
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#include "student.h"
#define cap 100
//Student constructor- empty
student::student()
{
id = 0;
first = "null";
last = "null";
age = 0;
gpa = 0.0;
}
//Student deconstructor
student::~student()
{
}
bool student::get(istream &in)
{
in >> id >> first >> last >> age >> gpa;
return(in.good());
}
void student::put(ostream &out)
{
out << id << first << last << age << gpa;
}
bool student::operator>(student)
{
if(student[i].id>student[i+1].id)
return true;
else
return false;
cout << student[i].id;
}
bool student::operator<(student)
{
if(student[i].id<student[i+1].id)
return true;
else
return false;
}
void student::sort_array()
{
int j,temp;
for(j=0;j<cap-1;j++)
{
//if out of position switch the out of align number
if(student[i].id<student[i+1].id)
{
temp = student[i].id;
student[i].id = student[i+1].id;
student[i+1].id = temp;
}
}
}
This is my file, and my main code that would display the and call functions
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
#include "student.h"
#define cap 100
void main()
{ string s;
class student student[cap],l;
int i;
fstream f;
i=0;
cout << "Enter the file name: "; //Display to enter the file name
cin >>s;
f.open(s.data(),ios::in);
if(!f.is_open())
cout << "could not open file";
while(i<cap && !f.eof())
{
student[i].get(f);
//Display if okay
if(f.good())
{
student[i].sort_array();
i++;
cout << i;
}
}
f.close();
}
this is my class code, and class file
#include <iostream>
using namespace std;
class student
{
public:
student(); //Constructor without parameters
student(int,string,string,int,float); //Constructor with parameters
~student(); //Deconstructors
bool get(istream &); //Input
void put(ostream &); //Output
bool operator==(student);
bool operator>(student);
bool operator<(student);
bool operator==(int);
bool operator>(int);
bool operator<(int);
int read_array(string,int);
void sort_array();
private:
int id,age;
float gpa;
string last,first;
};

The common technique is to provide comparison operators, <, >, <=, >=, == and !=, for a class that can be compared. Most sort algorithms require that items in the container can be "less than comparable".
Look up the Boost library as it has tools that will define all comparison operators when only less-than and equality are defined.
In your design, you will need a container for your students. Use std::sort or your preferred sorting function on the container. If this is homework, you may want to put the container in main() along with the sorting logic.
Also, either search the web for "C++ overloading operators" or define your own method. If you are clever, you can design your class to have different comparison functions to allow sorting by the different fields.

Related

Use of undeclared identifiers even though class is created in c++

I have created a class ShowTicket coded as follows in a header file:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
class ShowTicket {
public:
//function that returns true if sold status is true and false if it doesnt.
bool is_sold(void){
if (sold_status == true){
return true;
}
else{
return false;
}
}
//function that sets sold_status to true
void sell_seat(void){
sold_status = true;
}
//prints row, seat number and sold status in casual terms
string print_ticket(void){
ostringstream sout;
if(sold_status == true){
sout<<row<<" "<<seat_number<<"sold";
}
else{
sout<<row<<" "<<seat_number<<"available";
}
return sout.str();
}
//initilizes variables in constructor
bool sold_status;
const char* row;
const char* seat_number;
//constructor
ShowTicket(const char* row, const char* seat_number, bool sold_status){
sold_status = false;
}
};
I am using a main file with the following code to test this class
#include <iostream>
#include <string>
#include <sstream>
#include "showticket.h"
using namespace std;
int main () {
ShowTicket myticket1(“AA”,”101");
ShowTicket myticket2(“AA”,”102”);
if(!myticket1.is_sold())
myticket1.sell_seat ();
cout << myticket1.print_ticket() << endl;
cout << myticket2.print_ticket() << endl;
return 0;
}
I am receiving multiple "Use of undeclared identifier" errors and "Non-ASCII characters are not allowed outside of literals" errors and I do not know how to fix them.
Any help is greatly appreciated.

How would I use a friend method that is predefined in a header file?

Essentially, my Computer Science teacher is making me use the friend std::ostream method for output.. I have imported it into the header file as one can see below, but I have no clue how to use it in the student.cpp. Adding student::ostream did not work. How would I be able to use the header predefined method in my student.cpp
My header file
#pragma once
#include <iostream>
class student
{
public:
student();
std::string settingStudentName;
bool disiplineIssue();
// provided again so you learn this valuable override method for printing class data.
friend std::ostream& operator << (std::ostream& const student &);
private:
std::string studentName;
bool hasDisciplineIssue;
};
Student.cpp
#include "student.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
student::student()
{
}
bool student::disiplineIssue()
{
// Max the random integer can go
int max = 100;
srand(time(0));
int random = rand()%max;
// bool variable for returning
bool True_or_False = false;
if (random <= 5)
{
True_or_False = true;
}
return True_or_False;
}
ostream& operator<< (ostream& output, const student& aStudent) {
output << aStudent.studentName << " ";
if (aStudent.hasDisciplineIssue) {
output << "has ";
}
else {
output << "doesn't have ";
}
output << "a discipline issue";
return output;
}
Edit:
When I do not have student:: in front, ostream works but if I add student:: in front, it says it can not resolve the symbol. I am not sure if the one without student:: is using the one I defined in the header file.
I would proceed in the following manner:
add body and declaration parameters to function settingStudentName in both header and main file;
insert correct dependancies (#include);
add a main() driver function;
also, use correct syntax (friend std::ostream& operator << (std::ostream&, const student &);) lacked the comma , separator between the function arguments.
A MWE:
#ifndef STUDENT_H_INCLUDED
#define STUDENT_H_INCLUDED
#include <iostream>
#include <string>
class student
{
public:
student();
std::string settingStudentName(const std::string&);
bool disiplineIssue();
// provided again so you learn this valuable override method for printing class data.
friend std::ostream& operator << (std::ostream&, const student &);
private:
std::string studentName;
bool hasDisciplineIssue;
};
#endif // STUDENT_H_INCLUDED
#include "student.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
student::student()
{
}
string student::settingStudentName(const string& input)
{
studentName = input;
return input;
}
bool student::disiplineIssue()
{
// Max the random integer can go
int max = 100;
srand(time(0));
int random = rand()%max;
// bool variable for returning
bool True_or_False = false;
if (random <= 5)
{
True_or_False = true;
}
return True_or_False;
}
ostream& operator<< (ostream& output, const student& aStudent) {
output << aStudent.studentName << " ";
if (aStudent.hasDisciplineIssue) {
output << "has ";
}
else {
output << "doesn't have ";
}
output << "a discipline issue";
return output;
}
int main()
{
student Jack;
Jack.settingStudentName("Jack");
Jack.disiplineIssue();
cout << Jack << endl;
return 0;
}
Here is the output:
Jack has a discipline issue
And here is a compiled version you can play with https://wandbox.org/permlink/mF49xQxkXs3M7n0M

C++ - initializing static vector of pointers causes undefined reference

I'm trying to create a function below in my CreateReport class called load() that copies all the records (data) from my graduate.dat file into my static vector of Record pointers called primaryCollection. I created a Record class with variables that make up each Record, and in my load() function in createReport.cc I attempted to read each line in the file, create a Record object with each line, add it to my vector, and then print everything in primaryCollection.
The problem is every time I attempt to use primaryCollection, I keep getting the error:
CreateReport.o: In function `CreateReport::CreateReport()':
CreateReport.cc:(.text+0x43): undefined reference to `CreateReport::primaryCollection'
CreateReport.o: In function `CreateReport::load()':
CreateReport.cc:(.text+0x2ac): undefined reference to `CreateReport::primaryCollection'
CreateReport.cc:(.text+0x31d): undefined reference to `CreateReport::primaryCollection'
CreateReport.cc:(.text+0x32f): undefined reference to `CreateReport::primaryCollection'
I get 4 undefined references for the 4 times I mention primaryCollection in createReport.cc. I'm not sure if I'm initializing primaryCollection correctly and if that is whats causing these undefined references. I don't know if this is relevant to my problem, but CreateReport is also an abstract class and has a few subclasses called ReportOne, ReportTwo, etc.
primaryCollection is supposed to be a static vector of Record pointers and I'm also not allowed to use std::map for this task.
I would appreciate any help with this issue. I looked at this post Undefined reference to static variable c++ but I still don't really understand what to do. I'm not allowed to make global variables and I'm dealing with a collection rather than a single variable.
My graduate.dat file is formatted like below in the format < year province degree >
2000 AB Bachelor's
2005 AB Bachelor's
2005 MB College
Each line basically represents a Record. So the first record here is 2000 AB Bachelor's
EDIT: So I made changes to my code based on the comments by adding the line vector<Record*> CreateReport::primaryCollection; above my constructor, but it gives me the error:
CreateReport.cc:13:34: error: conflicting declaration ‘std::vector<Record*> CreateReport::primaryCollection’
vector<Record*> CreateReport::primaryCollection;
^~~~~~~~~~~~~~~~~
In file included from CreateReport.cc:5:0:
CreateReport.h:23:33: note: previous declaration as ‘std::vector<Record*>* CreateReport::primaryCollection’
static std::vector<Record*>* primaryCollection; //STL vector of record pointers
^~~~~~~~~~~~~~~~~
CreateReport.cc:13:34: error: declaration of ‘std::vector<Record*>* CreateReport::primaryCollection’ outside of class is not definition [-fpermissive]
vector<Record*> CreateReport::primaryCollection;
Any ideas how to fix this?
Record.h
#ifndef RECORD_H
#define RECORD_H
#include <iostream>
#include <string>
class Record{
public:
Record(int = 0, string = "", string = "");
~Record();
private:
int year;
string province;
string degree;
};
#endif
Record.cc
#include <iostream>
#include <string>
using namespace std;
#include "Record.h"
Record::Record(int i1, string s1, string s2) : year(i1), province(s1), degree(s2){}
Record::~Record(){}
CreateReport.h
#ifndef CREATEREPORT_H
#define CREATEREPORT_H
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
#include <cstdlib>
#include "Record.h"
class CreateReport{
public:
CreateReport();
static void load();
protected:
static vector<Record*> primaryCollection; //STL vector of record pointers
};
#endif
CreateReport.cc
#include <iostream>
using namespace std;
#include <string>
#include "CreateReport.h"
vector<Record*> CreateReport::primaryCollection;
CreateReport::CreateReport(){
}
void CreateReport::load(){
int year;
string province, degree;
ostream_iterator<Record*> outItr(cout);
ifstream infile("graduate.dat", ios::in);
if (!infile) {
cout << "Error: could not open file" << endl;
exit(1);
}
while (infile >> year >> province >> degree) { //as long as were not at end of file
Record* record = new Record(year, province, degree); //create Record object with this data
primaryCollection->push_back(record); //undefined reference
}
cout<<endl<<"List of Records:"<<endl;
copy(primaryCollection->begin(), primaryCollection->end(), outItr); //2 undefined references
}
Second version using `Record*` for `std::vector primaryCollection`.
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
class Record{
public:
Record(int = 0, string = "", string = "");
~Record()=default;
friend std::ostream& operator<<(std::ostream&, const Record&);
private:
int year;
string province;
string degree;
};
// **** output overload for Record ***********
std::ostream& operator<<(std::ostream& os, const Record& rd)
{
os << "year = " << rd.year << " prov = " << rd.province << " degree = " << rd.degree << std::endl;
return os;
}
// ****** end of output overload **************
Record::Record(int i1, string s1, string s2) : year(i1), province(s1), degree(s2){}
//end of Record.cc
//
class CreateReport{
public:
CreateReport() = default;
void load();
protected:
static vector<Record*> primaryCollection; //STL vector of record pointers
};
//***************** you need this line ********************
std::vector<Record*> CreateReport::primaryCollection;
//*********************************************************
void CreateReport::load(){
int year;
string province, degree;
ifstream infile("graduate.dat", ios::in);
if (!infile) {
cout << "Error: could not open file" << endl;
exit(1);
}
while (infile >> year >> province >> degree) {
Record *a = new Record(year, province, degree);
primaryCollection.push_back( a );
}
cout<<endl<<"List of Records:"<<endl;
for (int i = 0; i<primaryCollection.size(); ++i ) std::cout << *primaryCollection[i];
}
int main()
{
CreateReport mime;
mime.load();
}
Three major problems:
Using std::vector<*Record> cause many un-necessary difficulties;
For static member vector, a extra definition outside the class is necessary.std::vector<Record> CreateReport::primaryCollection;. This erases the undefined error message.
Using copy to std::cout doesn't work, it provide no method of printing Record. Suggest to write a output overload.
Based on these, I provide a version as follows (mixed all headers together.)
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
using namespace std;
class Record{
public:
Record(int = 0, string = "", string = "");
~Record()=default;
friend std::ostream& operator<<(std::ostream&, const Record&);
private:
int year;
string province;
string degree;
};
// **** output overload for Record ***********
std::ostream& operator<<(std::ostream& os, const Record& rd)
{
os << "year = " << rd.year << " prov = " << rd.province << " degree = " << rd.degree << std::endl;
return os;
}
// ****** end of output overload **************
Record::Record(int i1, string s1, string s2) : year(i1), province(s1), degree(s2){}
//end of Record.cc
//
class CreateReport{
public:
CreateReport() = default;
void load();
protected:
static vector<Record> primaryCollection;
};
//***************** you need this line ********************
vector<Record> CreateReport::primaryCollection;
//*********************************************************
void CreateReport::load(){
int year;
string province, degree;
ifstream infile("graduate.dat", ios::in);
if (!infile) {
cout << "Error: could not open file" << endl;
exit(1);
}
while (infile >> year >> province >> degree) {
primaryCollection.push_back( Record(year, province, degree) );
}
cout<<endl<<"List of Records:"<<endl;
for (int i = 0; i<primaryCollection.size(); ++i ) std::cout << primaryCollection[i];
}
int main()
{
CreateReport mime;
mime.load();
}

My getlines are showing an error as well as my get functions when I put in a variable in the parentheses c++

I have a banking project and I am trying to set up the bank name, address, and working hours. My getlines are showing an error as well as my get functions.
Input exact error messages here please.
'getline': no matching overloaded function found
no suitable user-defined conversion from "Bank" to "std::string" exists
Here's the class for bank:
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cctype>
#include <cstdlib>
using namespace std;
class Bank {
public:
void setBankName(string bn) { bn = bankname; }
string getBankName() { return bankname; }
void setBankAdd(string ba) { ba = bankadd; }
string getBankAdd() { return bankadd; }
void setWorkingHours(string bwh) { bwh = bankworkinghours; };
string getWorkingHours() { return bankworkinghours; }
private:
string bankname, bankadd, bankworkinghours;
};
//and then this is in my main function
int main() {
Bank bankname, bankadd, bankworkinghours;
char userChoice; // numbers 1-9
int number=0;
system ("color 5f");
cout << "Name of bank: ";
getline(cin, bankname); **//all the get lines also show error**
cout << endl;
cout << "Bank address: ";
getline(cin, bankadd);
cout << endl;
cout << "Bank working hours: ";
getline(cin, bankworkinghours);
cout << endl;
bankname.setBankName(bankname); //the things in the parentheses show error
bankadd.setBankAdd(bankadd);
bankworkinghours.setWorkingHours(bankworkinghours);
The error is self explanatory. 2nd parameter of getline function is std:string so define bankname as std:string and then set the name of bank object by setBankName.
1- You did not created bank Object in the main to set class attributes.
You need an Object with reference to that object you will set the parameters of the class bank.
2- bankname, bankadd, bankworkinghours are string and you made them Bank
Here is updated code and working fine in VS 2019 without any error. Just a few changes in the first 2 and last three lines of main
#include <iostream>
#include <string>
#include <vector>
#include <ctime>
#include <cctype>
#include <cstdlib>
using namespace std;
class Bank {
public:
void setBankName(string bn) { bn = bankname; }
string getBankName() { return bankname; }
void setBankAdd(string ba) { ba = bankadd; }
string getBankAdd() { return bankadd; }
void setWorkingHours(string bwh) { bwh = bankworkinghours; };
string getWorkingHours() { return bankworkinghours; }
private:
string bankname, bankadd, bankworkinghours;
};
//and then this is in my main function
int main() {
Bank bankObj;
string bankname, bankadd, bankworkinghours;
char userChoice; // numbers 1-9
int number = 0;
system("color 5f");
cout << "Name of bank: ";
getline(cin, bankname);
cout << endl;
cout << "Bank address: ";
getline(cin, bankadd);
cout << endl;
cout << "Bank working hours: ";
getline(cin, bankworkinghours);
cout << endl;
bankObj.setBankName(bankname);
bankObj.setBankAdd(bankadd);
bankObj.setWorkingHours(bankworkinghours);
}
void setBankName(string bn) { bn = bankname; } is the wrong way around. try bankname = bn.

Comparing stacks

I have a project to compare the contents of two stacks and I am having issues with this function. I believe I have the rest of the program done correctly. I am getting errors on B.myCharacters.empty() (Expression must have class type) and B==B.myCharacters (no operator "==" matched these operands).
bool CharStack::IsEqual(CharStack & B)
{
if (B.empty())
{
cout << "Stack is empty" << endl;
return false;
}
else if (B.myCharacters.empty())
{
cout << "Stack is empty" << endl;
return false;
}
else if (B == B.myCharacters)
return true;
}
Any help would be greatly appreciated.
Here is the header and driver. They were provided by the teacher for this project and I am not allowed to change them, even if there is a better way to do it.
#include <iostream>
#include <string>
using namespace std;
const int STACK_CAPACITY = 128;
typedef char StackElement;
class CharStack
{
private:
char myCharacters[STACK_CAPACITY]; // STL stack of chars.
int myTop;
public:
CharStack();
bool empty();
void push(const StackElement & value);
StackElement top() const;
void pop();
void StringToStack(const string & inStr);
friend ostream & operator <<(ostream & out, const CharStack & CS);
CharStack Reverse();
bool IsEqual(CharStack & B);
};
Driver
#include <string>
#include <cassert>
#include "Header.h"
using namespace std;
//introduces namespace std
int main(void)
{
ifstream in;
string fileName, line[30];
int i = 0;
CharStack N, M, P;
cout << "Enter file name for palindrome check: ";
cin >> fileName;
in.open(fileName.c_str());
assert(in.is_open());
while (!in.eof())
{
getline(in, line[i]);
N.StringToStack(line[i]);
cout << N << endl;
P = N;
M = N.Reverse();
if (P.IsEqual(M))
cout << "This line is a palindrome line" << endl;
else
cout << "This line is not a palindrome line" << endl;
i++;
}
cout << "\nProgram ended normally.\n";
system("pause");
}
Assuming your CharStack internally keeps the characters in a std::string, i.e.
class CharStack
{
std::string myCharacters; // internal data
public:
bool IsEqual(CharStack const&) const;
/* ... */
};
and IsEqual() should return if two stacks are identical, then the implementation is simply
bool CharStack::IsEqual(CharStack const&other) const
{
return myCharacters == other.myCharacters;
}
This compares an empty and a non-empty stack as not equal, but two empty stacks as equal, which arguably is the correct behaviour. If you want two empty stacks to be not equal you can
bool CharStack::IsEqualNonEmpty(CharStack const&other) const
{
return !myCharacters.empty() && myCharacters == other.myCharacters;
}
Note also the various uses of the keyword const.