How do I access the properties of this object? - c++

Okay, I've been battling this for awhile and I don't understand what I need to do. This is my LinkedList header.
// Non templated version
#pragma once
#ifndef __LINKEDLIST_H__
#define __LINKEDLIST_H__
// Get access to size_t definitions
#include <cstddef>
using std::size_t;
// A type alias for the stored type. Changing this changes what is stored
typedef int ItemType;
// Nodes for a linked list in C++
class Node
{
// A friend declaration allows LinkedList class to access the Node's private data
friend class LinkedList;
public:
Node(const ItemType& data, Node* next = nullptr);
private:
ItemType _data;
Node* _next;
};
// An linked list for C++
class LinkedList
{
public:
LinkedList();
LinkedList(const LinkedList&);
~LinkedList();
LinkedList& operator=(const LinkedList&);
ItemType pop_front();
ItemType& front();
void push_front(const ItemType& value);
void insert(size_t index, ItemType& data); // Replace these w/ iterators
void remove(size_t index);
size_t getSize() const;
private:
// Helper methods
void copy(const LinkedList &src);
void dealloc();
Node* find(size_t index) const;
// data
size_t _size;
Node *_head;
};
void LinkedList::insert(size_t index, Dweller &data){
Node* temp = this->_head;
while (temp->_next != NULL){
temp = temp->_next;
}
Node newNode = Node(data);
temp->_next = &newNode;
}
#endif
And this is my vault.h file:
#include <string>
#include <vector>
#include "linked_list.h"
using namespace std;
class Dweller{
public:
Dweller(const string& name, int& strength, int& agility, int& perception);
int getStrength();
int getAgility();
int getPerception();
string getName();
private:
string name;
int strength;
int agility;
int perception;
};
Dweller::Dweller(const string& name, int& strength, int& agility, int& perception){
if ((strength > 10) || (strength < 1)){
cout << "Invalid number." << endl;
}
if ((agility > 10) || (strength < 1)){
cout << "Invalid number." << endl;
}
if ((perception > 10) || (perception < 1)){
cout << "Invalid number." << endl;
}
this->name = name;
this->strength = strength;
this->agility = agility;
this->perception = perception;
}
int Dweller::getStrength(){
return this->strength;
}
int Dweller::getAgility(){
return this->agility;
}
int Dweller::getPerception(){
return this->perception;
}
string Dweller::getName(){
return this->name;
}
class Room{
public:
Room(const string& name, const string& statistic);
void print();
void add(Dweller&);
private:
string name;
string statistic;
LinkedList dwellers = LinkedList();
};
Room::Room(const string& name, const string& statistic){
this->name = name;
this->statistic = statistic;
}
void Room::add(Dweller& person){
dwellers.insert(0, person);
}
And the driver.cpp file that I can't edit. This is an assignment.
// driver.cpp
// Testing driver for Assignment 2
#include <iostream>
#include <locale>
#include <string>
#include "vault.h"
using std::cin;
using std::getline;
using std::cout;
using std::endl;
using std::string;
using std::locale;
using std::tolower;
int main()
{
std::locale loc;
// We create three rooms: Power Generator (Strength), Water Processing (Perception),
// and Diner (Agility)
Room power("Power Generator", "Strength");
Room water("Water Processing", "Perception");
Room diner("Diner", "Agility");
string prompt;
do
{
string charName;
cout << "What is the Dweller's name? ";
getline(cin, charName);
int str = 0, per = 0, agl = 0;
char room;
do
{
cout << "What is the character's Strength [1-10]? ";
cin >> str;
}
while(str <= 0 || str > 10);
do
{
cout << "What is the character's Perception [1-10]? ";
cin >> per;
}
while(per <= 0 || per > 10);
do
{
cout << "What is the character's Agility [1-10]? ";
cin >> agl;
}
while(agl <= 0 || agl > 10);
do
{
cout << "Which room [(P)ower, (W)ater, (D)iner]? ";
cin >> room;
room = tolower(room, loc);
}
while(room != 'p' && room != 'w' && room != 'd');
if(room == 'p')
power.add(Dweller(charName, str, per, agl));
else if(room == 'w')
water.add(Dweller(charName, str, per, agl));
else
diner.add(Dweller(charName, str, per, agl));
cout << "Are there more Dwellers [Y/N]? " << endl;
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Flush newlines
getline(cin, prompt);
}
while(tolower(prompt[0], loc) == 'y');
power.print();
water.print();
diner.print();
}
The problem I'm having is that I keep getting that I cannot convert from const Dweller to const ItemType.
What I'm trying to do is add a Dweller object to a linkedlist.

Is there a reason for the LinkList class? If not why not do something like this instead? Vector has pretty much everything you need on that. Some other advice is don't use std::endl unless you need to do a flush. instead use \n.
// Get access to size_t definitions
#include <vector>
#include <iostream>
#include <locale>
#include <string>
class Dweller{
public:
Dweller(const std::string name, int strength, int agility, int perception);
int getStrength();
int getAgility();
int getPerception();
std::string getName();
private:
std::string name_;
int strength_;
int agility_;
int perception_;
};
Dweller::Dweller(const std::string name, int strength, int agility, int perception) :
name_{name},
strength_{strength},
agility_{agility},
perception_{perception}
{
if (strength > 10 || strength < 1) {
std::cout << "Invalid number.\n";
}
if ((agility > 10) || (strength < 1)){
std::cout << "Invalid number.\n";
}
if ((perception > 10) || (perception < 1)){
std::cout << "Invalid number.\n";
}
}
int Dweller::getStrength(){
return strength_;
}
int Dweller::getAgility(){
return agility_;
}
int Dweller::getPerception(){
return perception_;
}
std::string Dweller::getName(){
return name_;
}
class Room{
public:
Room(const std::string name, const std::string statistic);
void print();
void add(Dweller&);
private:
std::string name_;
std::string statistic_;
std::vector<Dweller> dwellers_;
};
Room::Room(const std::string name, const std::string statistic) :
name_{name},
statistic_{statistic}
{}
void Room::print()
{
for (auto& iter : dwellers_) {
std::cout << "\nName: " << iter.getName()
<< "\nStrength: " << iter.getStrength()
<< "\nAgility: " << iter.getAgility()
<< "\nPerception: " << iter.getPerception();
}
}
void Room::add(Dweller& person)
{
dwellers_.push_back(person);
}
int main()
{
std::locale loc;
// We create three rooms: Power Generator (Strength), Water Processing (Perception),
// and Diner (Agility)
Room power("Power Generator", "Strength");
Room water("Water Processing", "Perception");
Room diner("Diner", "Agility");
std::string prompt;
do
{
std::string charName;
std::cout << "What is the Dweller's name? ";
std::getline(std::cin, charName);
int str = 0, per = 0, agl = 0;
char room;
do
{
std::cout << "What is the character's Strength [1-10]? ";
std::cin >> str;
} while (str <= 0 || str > 10);
do
{
std::cout << "What is the character's Perception [1-10]? ";
std::cin >> per;
} while (per <= 0 || per > 10);
do
{
std::cout << "What is the character's Agility [1-10]? ";
std::cin >> agl;
} while (agl <= 0 || agl > 10);
do
{
std::cout << "Which room [(P)ower, (W)ater, (D)iner]? ";
std::cin >> room;
room = tolower(room, loc);
} while (room != 'p' && room != 'w' && room != 'd');
if (room == 'p')
power.add(Dweller(charName, str, per, agl));
else if (room == 'w')
water.add(Dweller(charName, str, per, agl));
else
diner.add(Dweller(charName, str, per, agl));
std::cout << "Are there more Dwellers [Y/N]? \n";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // Flush newlines
std::getline(std::cin, prompt);
} while (tolower(prompt[0], loc) == 'y');
power.print();
water.print();
diner.print();
std::cout << '\n';
system("PAUSE");
}

Start by making it possible to do what you want. Change the definition of Node to be templated
template <class ItemType>
class Node
{
//node, but with a few tweaks to replace the typedef of ItemType with the templating
}
Ditto with LinkedList
template <class ItemType>
class LinkedList
{
//lots of tweaks to replace node with templated node
...
Node<ItemType> *_head;
};
Then when you need to make the list:
LinkedList<Dweller> dwellers;

Related

How do I create a template object based off of user input?

I have made an array based queue with a template so that the user can decide what kind of data is held inside the queue but I cannot figure out how gather input and then from that create a queue of that data type.
Here is my Queue
#include <memory>
using namespace std;
template<class itemType>
class Queue
{
private:
unique_ptr<itemType []> queueArray;
int queueSize;
int front;
int rear;
int numItems;
public:
Queue(int);
itemType peekFront();
void enqueue(itemType item);
void dequeue();
bool isEmpty() const;
bool isFull() const;
void clear();
};
And I have tried this and many other ways but cant figure out how to tell what type of data the user inputs and then create a Queue with that type of data.
int main()
{
const int MAXSIZE = 5;
int choice;
cout << "1. integer queue\n" << "2. string queue\n" << "3. float queue\n";
choice = menu();
if(choice == 1)
{
Queue<int> newQueue(MAXSIZE);
int data;
}
else if(choice == 2)
{
Queue<string> newQueue(MAXSIZE);
string data;
}
else if(choice == 3)
{
Queue<float> newQueue(MAXSIZE);
float data;
}
else
cout << "Number needs to be 1-3." << endl;
cout << "Enter an item to add" << endl;
cin >> data;
newQueue->enqueue(data);
Thanks everyone for the help! I almost have it done, but now that I have all virtual functions how do I call peekFront()? Since the virtual functions can't return itemType right?
You need runtime polymorphism to solve this problem. This can either be achieved with a base class:
class IQueue {
virtual ~IQueue() = default;
virtual void enqueue(istream&) = 0;
};
template<class itemType>
class Queue : public IQueue
{
//...
public:
void enqueue(istream& is) override {
itemType item;
is >> item;
enqueue(item);
}
//...
};
And use as a pointer
int main() {
//...
unique_ptr<IQueue> newQueue;
//...
if(choice == 1)
{
newQueue.reset(new Queue<int>(MAXSIZE));
int data;
}
//...
newQueue->enqueue(cin);
//...
}
Or something like std::variant.
Well, you are almost there.
You just need to not loose the scope of your data and newQueue variables.
template <typename T>
T input()
{
T data;
cout << "Enter an item to add" << endl;
cin >> data;
return data;
}
int main()
{
const int MAXSIZE = 5;
int choice;
cout << "1. integer queue\n" << "2. string queue\n" << "3. float queue\n";
choice = menu();
if(choice == 1)
{
Queue<int> newQueue(MAXSIZE);
newQueue->enqueue(input<int>());
}
else if(choice == 2)
{
Queue<string> newQueue(MAXSIZE);
newQueue->enqueue(input<string>());
}
else if(choice == 3)
{
Queue<float> newQueue(MAXSIZE);
newQueue->enqueue(input<float>());
}
else
cout << "Number needs to be 1-3." << endl;
}
You still have some problem with this architecture, for example, maybe you want to move your queues outside these ifs, otherwise you can't use them anymore. (Read about scope).
You could also look at std::variant for these kind of situations.

Making vector of objects by class

I have recently tried to learn how to create an object of vectors in order to represent objects of students including their names and grades. but when I wrote my program I got some errors regarding using &. I do not know what is the problem with my errors. could you please help me to fix it?
#include <iostream>
#include <vector>
#include <string>
using namespace std;
void printvector(const vector< student>&); // fill vector.fill in student information
void fillvector(vector< student>&); // print the information of all students
class student {
public:
student();
student(string, char);
~student();
string getName() ;
char getGrade() ;
void setName(string);
void setGrade(char);
private:
string newName;
char newGrade;
};
student::student() { newGrade = ' '; }
student::student(string name, char grade) {
newName = name;
newGrade = grade;
}
student::~student(){ }
string student::getName() { return newName; }
char student::getGrade() { return newGrade; }
void student::setName(string name) { newName = name; }
void student::setGrade(char grade) { newGrade = grade; }
int main() {
vector<student> myclass;
printvector(myclass);
fillvector(myclass);
return 0;
}
void fillvector(vector< student>& newmyclass) {
string name;
char grade;
int classsize;
cout << "how many students are in your class?";
cin >> classsize;
for (int i = 0; i < classsize; i++) {
cout << "enter student name";
cin >> name;
cout << "enter student grade";
cin >> grade;
student newstudent(name, grade);
newmyclass.push_back(newstudent);
cout << endl;
}
}
void printvector( vector< student>& newmyclass) {
unsigned int size = newmyclass.size();
for (unsigned int i = 0; i < size; i++) {
cout << "student name:" << newmyclass[i].getName() << endl;
cout << endl;
cout << "student grade" << newmyclass[i].getGrade() << endl;
cout << endl;
}
}
It seems you're printing your vector before filling it.. Is your problem fixed when you swap them around?
int main() {
vector<student> myclass;
printvector(myclass); // <--- These two lines should probably be swapped
fillvector(myclass); // <---
return 0;
}

no viable conversion from 'int' to 'student' c++

(Edited version)
I am currently coding Binary Search Tree algorithm. (using xCode IDE)
I'm taking the data from txt file and insert it as binarysearchtree.
This is the sample of data from txt file.
3800 Lee, Victor; 2.8
3000 Brown, Joanne; 4.0
As you can see in student.h, there are 2 variables which are id and student. Id contains the data "3800" and student contains "Lee, Victor; 2.8". Each line of the txt consider as one root.
Now, I have to search by a unique key which is id(Ex. "3800") and print out if it is found in the tree.
I have 5 files, BinaryNode.h, BinaryTree.h, BinarySearchTree.h, Student.h, main.cpp.
All 3 of the binary header file are using template and Student.h has no template.
So, here is my int main.
int main()
{
BinarySearchTree<Student> tree;
getData(tree); (I didn't include getData part, but consider tree has txtfile data.)
bool found = false;
char input;
do
{
cout << "Enter a key letter to access to a corresponding menu." << endl << endl;
cout << "T – Print tree as an indented list" << endl;
cout << "S – Search by a unique key (student ID)" << endl;
cout << "B – Tree Breadth-First Traversal: Print by level" << endl;
cout << "D – Depth-First Traversals: inorder, preorder, postorder" << endl;
cout << "R – Find the longest branch and print it (from leaf to root)" << endl;
cout << "H – Help" << endl;
cout << "Q – Quit" << endl << endl;
cout << "Input: ";
cin >> input;
cout << endl;
if(input == 'T' || input == 'S' || input == 'B' || input == 'D' || input == 'R' || input == 'H' || input == 'Q' || input == 'A')
{
if(input == 'T')
{
//print tree as indented
}
else if(input == 'S')
{
//search by student ID
Student *result = new Student;
int id;
cout << "Enter the student ID to search the matching student." << endl;
cin >> id;
result->setId(id);
found = tree.getEntry(*result);
}
I cin the input data into result and tried to search for the data.
//My getEntry function in public function definition
template<class ItemType>
bool BinarySearchTree<ItemType>::getEntry(ItemType& anEntry)
{
BinaryNode<ItemType>* returnedItem = findNode(BinaryTree<ItemType>::rootPtr, anEntry);
if (returnedItem)
{
anEntry = returnedItem->getItem();
return true;
}
else return false;
}
//findNode function
template<class ItemType>
BinaryNode<ItemType>*
BinarySearchTree<ItemType>::findNode(BinaryNode<ItemType>* nodePtr,
ItemType & target)
{
ItemType result = result.getId(); <------- ******error here*******
ItemType root = nodePtr->getItem().getId();
if (nodePtr == nullptr)
return nullptr;
if (result == root)
return root;
if (result > root)
root = findNode(nodePtr->getRightPtr(), target);
else
root = findNode(nodePtr->getLeftPtr(), target);
return root;
}
I have an error on my findNode function.
->No viable conversion from 'int' to 'Student'
//Student.h
class Student
{
private:
int id;
std::string name;
public:
Student() { id = 0; name = ""; }
Student(int newId, std::string newName) { id = newId; name = newName; }
friend bool operator >= (const Student l, const Student& r)
{
return std::tie(l.id, l.name) < std::tie(r.id, r.name);
}
friend bool operator == (const Student l, const Student& r)
{
return std::tie(l.id, l.name) < std::tie(r.id, r.name);
}
friend bool operator < (const Student l, const Student& r)
{
return std::tie(l.id, l.name) < std::tie(r.id, r.name);
}
friend bool operator > (const Student l, const Student& r)
{
return std::tie(l.id, l.name) < std::tie(r.id, r.name);
}
/*
Student& operator = (Student& t_id)
{
if(this != &t_id)
id = t_id.getId();
return *this;
}
*/
void getStudent() { std::cin >> id; }
int getId() const { return id; }
void setId(int t_id) { id = t_id; }
std::string getName() const { return name; }
void setName(std::string t_name) { name = t_name; }
//ItemType getGpa() const { return gpa; }
//virtual void setGpa(std::string t_gpa) { gpa = t_gpa; }
Do I need = operator to fix that problem?
Actually, I created the = operator but if I enable that = operator code,
the other codes with equal sign that are in other functions
encounter errors. (no viable overloaded '=')
How can I fix this errors?
Thank you for your helping.
Just see this line.
ItemType root = nodePtr->getItem().getId();
Do you feel that something is wrong here?

Output Is very slightly off in ordered traversal of Binary search tree

#ifndef MOVIETREE_H_INCLUDED
#define MOVIETREE_H_INCLUDED
#include <iostream>
#include <cstdlib>
#include <vector>
#include <math.h>
using namespace std;
class BinarySearchTree
{
private:
struct tree_node
{
tree_node* left;
tree_node* right;
int ranking;
string title;
int year;
int quantity;
};
tree_node* root;
public:
BinarySearchTree()
{
root = NULL;
}
bool isEmpty() const { return root==NULL; }
void insert(int ranking, string title, int year, int quantity);
void remove(string title);
void inorder(tree_node* p);
double orderrating(string title);
void print_inorder();
void search(string d);
void rent(string l);
// void split(const string& s, char c,vector<string>& v);
};
double BinarySearchTree::orderrating(string title)
{
// string letters[52]={"A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","o","p","q","r","s","t","u","v","w","x","y","z"};
char letters[54]={'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O',
'P','Q','R','S','T','U','V','W','X','Y','Z',':','a','b','c','d','e','f','g','h','i','j',
'k','l','m','o','p','q','r','s','t','u','v','w','x','y','z',' '};
double rating = 0;
for(int i = 0; i<title.length();i++)
{
for(int j = 0;j<52;j++)
{
if(letters[j]==title.at(i))
{
rating = rating+pow(10,-i)*((j)%26);
}
}
}
//cout<<rating<<endl;
return rating;
}
void split(const string& s, char c, vector<string>& v)
{
string::size_type i = 0;
string::size_type j = s.find(c);
while (j != string::npos) {
v.push_back(s.substr(i, j-i));
i = ++j;
j = s.find(c, j);
if (j == string::npos)
v.push_back(s.substr(i, s.length()));
}
}
void BinarySearchTree::insert(int ranking, string title, int year, int quantity)
{
tree_node* t = new tree_node;
tree_node* parent;
t->quantity = quantity;
t->ranking = ranking;
t->title = title;
t->year = year;
t->left = NULL;
t->right = NULL;
parent = NULL;
// is this a new tree?
if(isEmpty()) root = t;
else
{
//Note: ALL insertions are as leaf nodes
tree_node* curr;
curr = root;
// Find the Node's parent
while(curr)
{
parent = curr;
if(orderrating(t->title) > orderrating(curr->title)) curr = curr->right;
else curr = curr->left;
}
if(orderrating(t->title) <= orderrating(parent->title))
parent->left = t;
else
parent->right = t;
}
}
void BinarySearchTree::search(string l)
{
//Locate the element
bool found = false;
double d = orderrating(l);
if(isEmpty())
{
cout<<" This Tree is empty! "<<endl;
return;
}
tree_node* curr;
tree_node* parent;
curr = root;
while(curr != NULL)
{
if(curr->title == l)
{
found = true;
cout << "Movie Info:" << endl;
cout << "===========" << endl;
cout << "Ranking:" <<curr->ranking<<endl;
cout << "Title:"<<curr->title<<endl;
cout << "Year:" <<curr->year<<endl;
cout << "Quantity:"<<curr->quantity<<endl;
break;
}
else
{
parent = curr;
if(d>orderrating(curr->title)) curr = curr->right;
else curr = curr->left;
}
}
if(!found)
{
cout<<" Movie not found."<<endl;
return;
}
}
void BinarySearchTree::rent(string l)
{
//Locate the element
bool found = false;
double d = orderrating(l);
if(isEmpty())
{
cout<<"This Tree is empty!"<<endl;
return;
}
tree_node* curr;
tree_node* parent;
curr = root;
while(curr != NULL)
{
if(curr->title == l)
{
found = true;
if(curr->quantity!=0)
{curr->quantity = curr->quantity-1;
cout << "Movie has been rented." << endl;
cout << "Movie Info:" << endl;
cout << "===========" << endl;
cout << "Ranking:" <<curr->ranking<<endl;
cout << "Title:" <<curr->title<<endl;
cout << "Year:" <<curr->year<<endl;
cout << "Quantity:" << curr->quantity<<endl;
}
else{//If movie is in stock
cout << "Movie out of stock." << endl;
}
break;
}
else
{
parent = curr;
if(d>orderrating(curr->title)) curr = curr->right;
else curr = curr->left;
}
}
if(!found)
{
cout<<"Movie not found."<<endl;
return;
}
}
void BinarySearchTree::print_inorder()
{
inorder(root);
}
int counter =0;
void BinarySearchTree::inorder(tree_node* p)
{
if(p != NULL)
{
if(p->left) inorder(p->left);
cout<<"Movie: "<<p->title<<endl;
//cout<<" "<<p->quantity<<endl;//cout<<counter<<endl;
if(p->right) inorder(p->right);
}
else return;
}
#endif // MOVIETREE_H_INCLUDED
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include <stdlib.h>
#include "MovieTree.h"
using namespace std;
struct MovieInfo{
int ranking;
string title;
int year;
int quantity;
};
int main(int argc, char * argv[])
{
//creates struct to store movie info
MovieInfo MovieInfo1[51];
int counter1 = 0;
std::string word1;
//"Assignment5Movies.txt"
ifstream myfile1("Assignment5Movies.txt");
if (myfile1.is_open())
{
std::string line;
while ( getline (myfile1,line) )
{
//need delimeter for file.
vector<string> v;
string s = line;
split(s, ',', v);
for (unsigned int i = 0; i < v.size(); ++i)
//add individual atributes to moviearray
{//cout<<v[i]<<endl;
if(i%4==1){MovieInfo1[counter1].title = v[i];}
if(i%4==2){ int value =atoi(v[i].c_str()); MovieInfo1[counter1].year = value;}
if(i%4==3){ int value =atoi(v[i].c_str()); MovieInfo1[counter1].quantity = value;}
if(i%4==0){ int value =atoi(v[i].c_str()); MovieInfo1[counter1].ranking = value;}
}//cout<<counter1<<endl;
counter1++;
}
myfile1.close();
}
// construct Binary tree
BinarySearchTree b;
for(int i = 0; i<counter1;i++)
{
b.insert(MovieInfo1[i].ranking,MovieInfo1[i].title,MovieInfo1[i].year, MovieInfo1[i].quantity);
}
int option;
//do while loop for user interface
do{
cout << "======Main Menu=====" << endl;
cout << "1. Find a movie" << endl;
cout << "2. Rent a movie" << endl;
cout << "3. Print the inventory" << endl;
cout << "4. Quit" << endl;
cin>>option;
cin.ignore(10000,'\n');
if (option==1)//find movie
{
cout << "Enter title:" << endl;
string temp;
cin >> ws;
getline(cin, temp);
b.search(temp);
}
if (option==2)//rent movie
{
cout << "Enter title:" << endl;
string temp;
cin >> ws;
getline(cin, temp);
b.rent(temp);
}
if (option==3)//print inventory
{
b.print_inorder();
}
}while(option!=4);
cout << "Goodbye!" << endl;
}
here is my main file and my header, basically my output is off for like two movies and I don't know why. any input would be appreciated. and yes I should have used a string.compare(string) also when given a txt file it prints
12 Angry Men
Back to the Future
Casablanaca
... the rest are in order except
Lord of the Rings: the two towers
Lord of the Rings: the fellowship of the ring
Lord of the Rings: the return of the king
are in the right place, but ordered incorrectly.
The value of orderrating() for these three movies is identical. Therefore, they will be printed in the opposite order that you insert them into the tree.
Lord of the Rings: the two towers
Lord of the Rings: the fellowship of the ring
Lord of the Rings: the return of the king
There's only so much precision in a double.

Inserting an object into a C++ Sequential list

For a school programming assignment I built an application that stores a list of objects in a sequential list object. The sequential list class has a method to insert a new object into the list, it checks first to see if the list already has the maximum number of entries allowed and if it does returns an error. For some reason I'm unable to insert a new object into the list (I keep getting the "Max list size exceeded" error) even though there aren't any entries in it to start.
I ran it with a breakpoint to see if the size data member was increasing somehow but that doesn't seem to be the case here.
Please ignore the poor code quality, still just learning... Feel free to make any recommendations :)
Here's the main program:
#include<iostream>
#include<string>
#include "aseqlist.h"
using namespace std;
void PrintByGender (const SeqList& L, char gender)
{
int size = L.ListSize();
int count = 0;
while (count < size)
{
if (gender == L.GetData(count).getGender())
{
L.GetData(count).PrintEmployee();
}
count++;
}
}
int InList (const SeqList& L, char *lname, Employee& Emp)
{
int found = 0;
Emp.setLast(lname);
if (L.Find(Emp) == 1)
{
found = 1;
Emp.PrintEmployee();
}
return found;
}
int main()
{
SeqList obj1;
bool close = false;
string choice = "";
do
{
cout << "Please choose what you would like to do: " << "\n";
cout << "N = New record, D = Delete record, P = Print by gender, S = Search and E = Exit" << "\n";
cin >> choice;
cin.ignore();
if (choice == "n" || choice == "N")
{
string first, last;
int age;
char gen;
double empNum;
cout << "First name: ";
cin >> first;
cout << "Last name: ";
cin >> last;
cout << "Age: ";
cin >> age;
cout << "Gender ('M' Or 'F'): ";
cin >> gen;
cout << "Employee Number: ";
cin >> empNum;
Employee newEmp;
newEmp.ReadEmployee(first, last, age, gen, empNum);
obj1.Insert(newEmp);
}
if (choice == "e" || choice == "E")
{
close = true;
}
if (choice == "p" || choice == "P")
{
char genderSearch;
cout << "Male = M, Female = F";
cin >> genderSearch;
cin.ignore();
PrintByGender(obj1, genderSearch);
}
if (choice == "d" || choice == "D")
{
string last;
cout << "Which employee? (Enter Last Name): ";
cin >> last;
cin.ignore();
Employee emp;
emp.setLast(last);
obj1.Delete(emp);
cout << "Deleted";
}
if (choice == "s" || choice == "S")
{
char lnameSearch;
cout << "Last Name?: ";
cin >> lnameSearch;
cin.ignore();
Employee emp;
char *ptrSearch;
ptrSearch = &lnameSearch;
InList(obj1, ptrSearch, emp);
if (emp.getFirst() != "")
{
emp.PrintEmployee();
}
}
}
while (close != true);
};
And here's the header file for the class declarations:
#include <iostream>
using namespace std;
const int MaxListSize = 6;
// You will need to change the typedef in the following line
// from the data type int to Employee
class Employee
{
public:
Employee();
Employee(string firstName, string lastName, int age, char gender, double employeeNumber);
void ReadEmployee(string firstName, string lastName, int age, char gender, double employeeNumber);
char getGender();
string getFirst();
void Employee::setLast(string lname);
string getLast();
void PrintEmployee();
private:
string LastName;
string FirstName;
int Age;
char Gender;
double EmployeeNumber;
};
typedef Employee DataType;
class SeqList
{
private:
// list storage array and number of current list elements
DataType listitem[MaxListSize];
int size;
public:
// constructor
SeqList(void);
// list access methods
int ListSize(void) const;
int ListEmpty(void) const;
int Find (DataType& item) const;
DataType GetData(int pos) const;
// list modification methods
void Insert(const DataType& item);
void Delete(const DataType& item);
DataType DeleteFront(void);
void ClearList(void);
};
// Class Definition:
// constructor. set size to 0
SeqList::SeqList (void): size(6)
{}
// return number of elements in list
int SeqList::ListSize(void) const
{
return size;
}
// tests for an empty list
int SeqList::ListEmpty(void) const
{
return size == 0;
}
// clears list by setting size to 0
void SeqList::ClearList(void)
{
size = 0;
}
// Take item as key and search the list. return True if item
// is in the list and False otherwise. if found,
// assign the list element to the reference parameter item
bool operator==(Employee A, Employee B)
{
bool isequal = false;
if (A.getLast() == B.getLast())
isequal = true;
return isequal;
}
int SeqList::Find(DataType& item) const
{
int i = 0;
if (ListEmpty())
return 0; // return False when list empty
while (i < size && !(item == listitem[i]))
i++;
if (i < size)
{
item = listitem[i]; // assign list element to item
return 1; // return True
}
else
return 0; // return False
}
// insert item at the rear of the list. terminate the program
// if the list size would exceed MaxListSize.
void SeqList::Insert(const DataType& item)
{
// will an insertion exceed maximum list size allowed?
if (size+1 > MaxListSize)
{
cout << "Maximum list size exceeded" << endl;
exit(1);
}
// index of rear is current value of size. insert at rear
listitem[size] = item;
size++; // increment list size
}
// search for item in the list and delete it if found
void SeqList::Delete(const DataType& item)
{
int i = 0;
// search for item
while (i < size && !(item == listitem[i]))
i++;
if (i < size) // successful if i < size
{
// shift the tail of the list to the left one position
while (i < size-1)
{
listitem[i] = listitem[i+1];
i++;
}
size--; // decrement size
}
}
// delete element at front of list and return its value.
// terminate the program with an error message if the list is empty.
DataType SeqList::DeleteFront(void)
{
DataType frontItem;
// list is empty if size == 0
if (size == 0)
{
cout << "Attempt to delete the front of an empty list!" << endl;
exit(1);
}
frontItem = listitem[0]; // get value from position 0.
Delete(frontItem); // delete the first item and shift terms
return frontItem; // return the original value
}
// return value at position pos in list. if pos is not valid
// list position, teminate program with an error message.
DataType SeqList::GetData(int pos) const
{
// terminate program if pos out of range
if (pos < 0 || pos >= size)
{
cout << "pos is out of range!" << endl;
exit(1);
}
return listitem[pos];
}
Employee::Employee()
{
FirstName = "";
LastName = "";
Age = 0;
/*Gender = "";*/
EmployeeNumber = 0;
};
Employee::Employee(string firstName, string lastName, int age, char gender, double employeeNumber)
{
FirstName = firstName;
LastName = lastName;
Age = age;
Gender = gender;
EmployeeNumber = employeeNumber;
};
void Employee::PrintEmployee()
{
cout << "First Name: " << FirstName << "\n";
cout << "Last Name: " << LastName << "\n";
cout << "Age: " << Age << "\n";
cout << "Gender: " << Gender << "\n";
cout << "Employee Number :" << EmployeeNumber << "\n" << "\n";
};
void Employee::ReadEmployee(string firstName, string lastName, int age, char gender, double employeeNumber)
{
FirstName = firstName;
LastName = lastName;
Age = age;
Gender = gender;
EmployeeNumber = employeeNumber;
};
char Employee::getGender()
{
return Gender;
}
string Employee::getFirst()
{
return FirstName;
}
string Employee::getLast()
{
return LastName;
}
void Employee::setLast(string lname)
{
LastName = lname;
}
Problem in the constructor:
SeqList::SeqList (void): size(6)
size is being initialized as 6.
Other suggestions. Don't put using namespace std; in a header file. Better yet, don't put using namespace std; anywhere.
Why is "using namespace std" considered bad practice?
// constructor. set size to 0
SeqList::SeqList (void): size(6)
{}
This is wrong. Should be so:
// constructor. set size to 0
SeqList::SeqList (void): size(0)
{}