Cannot figure out constructor errors - c++

I have come across a couple of compiler errors in my code where it is saying. I have been working on this assignment and these seem to be the last two errors that I am comming across and would love some help on why it will not compile, I just want to go to bed :(
main.cpp:103:29: error: in c++98 'actors' must be initialized by constructor, not by '{...}'
list<string> actors = {};
and
main.cpp:138:19: warning: extended initializer lists only available with -std=c++11 or -std=gnu++11 [enabled by default]
actors = {};
Below is a copy of my two files! Thank you!
#include <iostream>
#include <list>
using namespace std;
class BST
{
// Defines the main components of the node object, as well as refrences the left and right elements
struct node
{
string show;
string year;
string genre;
string URL;
list <string> actors;
node*left;
node*right;
};
node* root;
// Deletes all the nodes of the tree
node* makeEmpty(node* t)
{
if(t == NULL)
{
return NULL;
}
else
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
return NULL;
}
// Inserts a node in the tree
node* insert(string x, string year, list<string> actors, node* t)// DO not include Genrem or URL
{
if(t == NULL)
{
t = new node;
t->show = x;
t->year = year;
t->actors = actors;
t->left = t->right = NULL;
}
else if(x < t-> show)
{
t->left = insert(x, year, actors, t->left);
}
else if(x > t-> show)
{
t->right = insert(x, year, actors, t->left);
}
else
{
return t;
}
}
//Finds the minimum most node to the left
node* findMin(node* t)
{
if(t == NULL)
{
return NULL;
}
else if(t->left == NULL)
{
return t;
}
else
{
return findMin(t->left);
}
}
// Finds the maximum most node to the right
node* findMax(node* t)
{
if(t == NULL)
{
return NULL;
}
else if(t->right == NULL)
{
return t;
}
else
{
return findMax(t->right);
}
}
// Finds a node with the given parameters
node* find(node* t, string x )
{
if(t == NULL)
{
return NULL;
}
else if(x.at(0) < t-> show.at(0))
{
return find(t->left, x);
}
else if(x.at(0) > t->show.at(0))
{
return find(t->right, x);
}
else
{
return t;
}
}
// Prints out the shows inorder
void inorder(node* t)
{
if(t == NULL)
{
// Do nothing
}
else
{
inorder(t->left);
cout << "- " << t->show << endl;
inorder(t->right);
}
}
// Prints the shows of a given actor
void findShow(node* t, string person, list<string> &list)
{
if(t == NULL)
{
// Do nothing
}
else
{
while(!t->actors.empty())
{
if(t->actors.front() == person)
{
list.push_front(t->show);
break;
}
t->actors.pop_front();
}
findShow(t->left, person, list);
findShow(t->right, person, list);
}
}
// Prints the shows within a given year
void findYear(node* t, string year, list<string> &list)
{
if(t == NULL)
{
// Do nothing
}
else
{
if(t->year == year)
{
list.push_front(t->show);
}
findYear(t->left, year, list);
findYear(t->right, year, list);
}
}
public:
BST()
{
root = NULL;
}
~BST()
{
root = makeEmpty(root);
}
// Public calls to modify the tree
// Inserts a node with the given parametersremove
void insert(string x, string year, list<string> actors)
{
root = insert(x, year, actors, root);
}
// Removes a node with the given key
// void remove(string x, node* t)
// {
// root = remove(x, root);
// }
// Displays all shows within the tree
void displayShows()
{
inorder(root);
}
// Displays all the actors with a given show
void displayActors(string show)
{
root = find(root, show);
if(root != NULL) // THIS LINE
{
list<string> temp = root-> actors;
while(!temp.empty())
{
cout << "- " << temp.front() << endl;
temp.pop_front();
}
}
else
{
cout << "root is NULL." << endl;
}
}
// Displays the shows of a given actor
void displayActorsShows(string actor)
{
list<string> show;
findShow(root, actor, show);
while(!show.empty())
{
cout << "- " << show.front() << endl;
show.pop_front();
}
}
// Searches the tree with the given node
void search(string x)
{
root = find(root, x);
}
};// end of class
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include "source.cpp"
using namespace std;
void scanFile(string fileName);
void printActors(string movie);
void printShows(string actor);
const int MAX_LINE = 128;
int movies = 0;
BST tree;
int main(){
// Scan file
scanFile("tvDB.txt");
// Print all the show titles
cout << "All show titles:" << endl;
tree.displayShows();
cout << endl; // Whitespace
// Print actors /w given show
cout << "Actors from 'The Saint'" << endl;
printActors("The Saint");
// Print show /w given actor
printShows("Tim Conway");
// Print from decade
return 0;
}
// Trims the line removing all excess whitespace before and after a sentence
string isolateLine(string line)
{
int index = 0, start = 0, end = 0;
//Get the start of the line
for(int i = 0; i < line.length(); i++)
{
if(line[i] != ' ' && line[i] != '\t')
{
start = i;
break;
}
}
// Get the end of the line
for(int x = line.length(); x >= 0; x--)
{
if(line[x] != ' ' && line[x] != '\t')
{
end = x;
break;
}
}
// Trim line
line = line.substr(start, end);
return line;
}
// A boolean that returns if the tree is blank, useful for skipping a line and continuing to search for a movie
bool blankLine(string line){
for(int i = 0; i < line.length(); i++)
{
if(line[i] != ' ' && line[i] != '\t')
{
return false;
}
}
return true;
}
// Prints all the shows an actor has starred in
void printShows(string actor){
cout << "Shows with [" << actor << "]:" << endl;
tree.displayActorsShows(actor);
cout << endl; // whitespace
}
// Prints all the actors in a particular movie
void printActors(string show)
{
cout << " Actors for [" << show << "]" << endl;
tree.displayActors(show);
cout << endl;
}
// Scans the fild and categorizes every line of data into the proper categories of the show
void scanFile(string fileName)
{
ifstream inFile;
inFile.open("tvDB.txt");
list <string> actors = {};
string line = "";
string title = "";
string year = "";
while(getline(inFile, line))
{
line = isolateLine(line);
if(!blankLine(line))
{
// Get movie title
if(line.find('(') != std::string::npos)
{
title = line.substr(0, line.find('(')-1);
}
// Get movie year
if (line.find('(') != std::string::npos) {
year = line.substr(line.find('(') + 1, line.find(')'));
year = year.substr(0, year.find(')'));
}
// Add to actors list
actors.push_back(line);
}
else
{
if(!actors.empty()) // pops the title
{
actors.pop_front();
}
}
tree.insert(title, year, actors);
actors = {};
movies++;
}
}

You have two options in this case:
Using C++11 is acceptable, in that case you can leave the code as-is but add -std=c++11 to your compilation flags (e.g. in your Makefile).
Replace usage of the initializer list:
list <string> actors = {}; -> list <string> actors; (documentation)
actors = {}; -> actors.clear(); (documentation)

Related

Cannot find source of segmentation fault

I have been working on this assignment for sometime and cannot figure out what is causing the segmentation fault, any help would be appreciated, here is a copy of my two files!
I am also in the process of fixing my inFile setup, but I would rather focus on that after the fact of the segmentation error.
#include <iostream>
#include <fstream>
#include <string>
#include <list>
#include "source.cpp"
using namespace std;
void scanFile(string fileName);
void printActors(string movie);
void printShows(string actor);
const int MAX_LINE = 128;
int movies = 0;
BST tree;
int main(){
// Scan file
scanFile("tvDB.txt");
// Print all the show titles
cout << "All show titles:" << endl;
tree.displayShows();
cout << endl; // Whitespace
// Print actors /w given show
cout << "Actors from 'The Saint'" << endl;
printActors("The Saint");
// Print show /w given actor
printShows("Tim Conway");
// Print from decade
return 0;
}
// Trims the line removing all excess whitespace before and after a sentence
string isolateLine(string line)
{
int index = 0, start = 0, end = 0;
//Get the start of the line
for(int i = 0; i < line.length(); i++)
{
if(line[i] != ' ' && line[i] != '\t')
{
start = i;
break;
}
}
// Get the end of the line
for(int x = line.length(); x >= 0; x--)
{
if(line[x] != ' ' && line[x] != '\t')
{
end = x;
break;
}
}
// Trim line
line = line.substr(start, end);
return line;
}
// A boolean that returns if the tree is blank, useful for skipping a line and continuing to search for a movie
bool blankLine(string line){
for(int i = 0; i < line.length(); i++)
{
if(line[i] != ' ' && line[i] != '\t')
{
return false;
}
}
return true;
}
// Prints all the shows an actor has starred in
void printShows(string actor){
cout << "Shows with [" << actor << "]:" << endl;
tree.displayActorsShows(actor);
cout << endl; // whitespace
}
// Prints all the actors in a particular movie
void printActors(string show)
{
cout << " Actors for [" << show << "]" << endl;
tree.displayActors(show);
cout << endl;
}
// Scans the fild and categorizes every line of data into the proper categories of the show
void scanFile(string fileName)
{
ifstream inFile;
inFile.open("tvDB.txt");
list <string> actors;
string line = "";
string title = "";
string year = "";
while(getline(inFile, line))
{
line = isolateLine(line);
if(!blankLine(line))
{
// Get movie title
if(line.find('(') != std::string::npos)
{
title = line.substr(0, line.find('(')-1);
}
// Get movie year
if (line.find('(') != std::string::npos) {
year = line.substr(line.find('(') + 1, line.find(')'));
year = year.substr(0, year.find(')'));
}
// Add to actors list
actors.push_back(line);
}
else
{
if(!actors.empty()) // pops the title
{
actors.pop_front();
}
}
tree.insert(title, year, actors);
actors.clear();
movies++;
}
}
and
#include <iostream>
#include <list>
using namespace std;
class BST
{
// Defines the main components of the node object, as well as refrences the left and right elements
struct node
{
string show;
string year;
string genre;
string URL;
list <string> actors;
node*left;
node*right;
};
node* root;
// Deletes all the nodes of the tree
node* makeEmpty(node* t)
{
if(t == NULL)
{
return NULL;
}
else
{
makeEmpty(t->left);
makeEmpty(t->right);
delete t;
}
return NULL;
}
// Inserts a node in the tree
node* insert(string x, string year, list<string> actors, node* t)// DO not include Genrem or URL
{
if(t == NULL)
{
t = new node;
t->show = x;
t->year = year;
t->actors = actors;
t->left = t->right = NULL;
}
else if(x < t-> show)
{
t->left = insert(x, year, actors, t->left);
}
else if(x > t-> show)
{
t->right = insert(x, year, actors, t->left);
}
else
{
return t;
}
}
//Finds the minimum most node to the left
node* findMin(node* t)
{
if(t == NULL)
{
return NULL;
}
else if(t->left == NULL)
{
return t;
}
else
{
return findMin(t->left);
}
}
// Finds the maximum most node to the right
node* findMax(node* t)
{
if(t == NULL)
{
return NULL;
}
else if(t->right == NULL)
{
return t;
}
else
{
return findMax(t->right);
}
}
// Finds a node with the given parameters
node* find(node* t, string x )
{
if(t == NULL)
{
return NULL;
}
else if(x.at(0) < t-> show.at(0))
{
return find(t->left, x);
}
else if(x.at(0) > t->show.at(0))
{
return find(t->right, x);
}
else
{
return t;
}
}
// Prints out the shows inorder
void inorder(node* t)
{
if(t == NULL)
{
// Do nothing
}
else
{
inorder(t->left);
cout << "- " << t->show << endl;
inorder(t->right);
}
}
// Prints the shows of a given actor
void findShow(node* t, string person, list<string> &list)
{
if(t == NULL)
{
// Do nothing
}
else
{
while(!t->actors.empty())
{
if(t->actors.front() == person)
{
list.push_front(t->show);
break;
}
t->actors.pop_front();
}
findShow(t->left, person, list);
findShow(t->right, person, list);
}
}
// Prints the shows within a given year
void findYear(node* t, string year, list<string> &list)
{
if(t == NULL)
{
// Do nothing
}
else
{
if(t->year == year)
{
list.push_front(t->show);
}
findYear(t->left, year, list);
findYear(t->right, year, list);
}
}
public:
BST()
{
root = NULL;
}
~BST()
{
root = makeEmpty(root);
}
// Public calls to modify the tree
// Inserts a node with the given parametersremove
void insert(string x, string year, list<string> actors)
{
root = insert(x, year, actors, root);
}
// Removes a node with the given key
// void remove(string x, node* t)
// {
// root = remove(x, root);
// }
// Displays all shows within the tree
void displayShows()
{
inorder(root);
}
// Displays all the actors with a given show
void displayActors(string show)
{
root = find(root, show);
if(root != NULL) // THIS LINE
{
list<string> temp = root-> actors;
while(!temp.empty())
{
cout << "- " << temp.front() << endl;
temp.pop_front();
}
}
else
{
cout << "root is NULL." << endl;
}
}
// Displays the shows of a given actor
void displayActorsShows(string actor)
{
list<string> show;
findShow(root, actor, show);
while(!show.empty())
{
cout << "- " << show.front() << endl;
show.pop_front();
}
}
// Searches the tree with the given node
void search(string x)
{
root = find(root, x);
}
};// end of class
I would suggest using a debugger (like GDB for unix or the VisualStudioBuildIn Debugger). There the SEG Fault is indicated in which variable the seg fault will be.
Also look out for correct initialized pointers (at least with = nullptr)
Btw: try to use nullptr instead of NULL, since it is not typesafe to use NULL.
Here is why: NULL vs nullptr (Why was it replaced?)

Alphabetically sorted links in doubly linked list

I've been having some trouble getting my program to insert given names along with their weights in a linked list which has a respective link for names and weights, which are both to be sorted in ascending / alphabetical order. The weight links work fine but I can't seem to identify what I'm getting wrong in my name linker. Any help would be greatly appreciated. The problem most likely lies in the insertName() private function.
#include <iostream>
#include <string>
using namespace std;
class DoublyLinkedList
{
public:
void insert(string name, double weight);
void printNameAsc();
void printWeightAsc();
private:
struct Node
{
string name;
double weight;
Node* nextName;
Node* nextWeight;
};
Node* nameHead = NULL;
Node* weightHead = NULL;
Node* newP = NULL;
void insertName();
void insertWeight();
};
void DoublyLinkedList::insert(string name, double weight)
{
// variable declaration
newP = new Node;
newP->name = name;
newP->weight = weight;
newP->nextName = NULL;
newP->nextWeight = NULL;
// empty first element check
if (nameHead == NULL && weightHead == NULL)
{
nameHead = newP;
weightHead = newP;
return;
}
// name and weight insertion
insertName();
insertWeight();
return;
}
void DoublyLinkedList::insertName()
{
Node* activeP = nameHead;
Node* prevP = NULL;
// traversing through name links
while (true)
{
if (activeP == NULL)
{
break;
}
if ((activeP->name).compare(newP->name))
{
break;
}
prevP = activeP;
activeP = activeP->nextName;
}
//insertion
newP->nextName = activeP;
if (activeP == nameHead)
{
nameHead = newP;
}
else
{
prevP->nextName = newP;
}
return;
}
void DoublyLinkedList::insertWeight()
{
Node* activeP = weightHead;
Node* prevP = NULL;
// traversing through weight links
while (true)
{
if (activeP == NULL)
{
break;
}
if (newP->weight < activeP->weight)
{
break;
}
prevP = activeP;
activeP = activeP->nextWeight;
}
//insertion
newP->nextWeight = activeP;
if (activeP == weightHead)
{
weightHead = newP;
}
else
{
prevP->nextWeight = newP;
}
return;
}
void DoublyLinkedList::printNameAsc()
{
Node* activeP = nameHead;
while (activeP != NULL)
{
cout << activeP->name << " " << activeP->weight << endl;
activeP = activeP->nextName;
}
return;
}
void DoublyLinkedList::printWeightAsc()
{
Node* activeP = weightHead;
while (activeP != NULL)
{
cout << activeP->name << " " << activeP->weight << endl;
activeP = activeP->nextWeight;
}
return;
}
int main()
{
DoublyLinkedList nameList;
nameList.insert("Michael", 275);
nameList.insert("Tom", 150);
nameList.insert("Abe", 200);
nameList.printNameAsc();
system("pause");
nameList.printWeightAsc();
system("pause");
return 0;
}
Pretty sure your problem is here:
if ((activeP->name).compare(newP->name) > 0)
{
break;
}
Looks like you're finding the insertion point with activeP. When activeP->name > newP->name, you want to stop searching.
if ((activeP->name).compare(newP->name))
Is invalid, this will evaluate true if activeP < newP (compare statement is -1) or activeP > newP (compare statement is 1), effectively only skipping people with the same names.
Remember, carried over from C, truth is defined as not falseness, which is defined as (!0)
Also, why not just pass a reference of newP to insertName() and insertWeight()? It's good practice to not leave (possibly dangling) pointers stored as member variables.

Priority Queue that utilizes BST -- DeleteLargest doesn't work

I am creating a priority queue that utilizes a binary search tree for my Data Structures class. But when I attempt to output the queue I always get 0. I have looked over my DeleteLargest and Dequeue member function but I can't find the mistake
Test.cpp
#include <iostream>
#include "CTree.h"
#include "PriorityQueueBST.h"
using namespace std;
int main()
{
int num, input, output;
cout << "Enter number of elements: ";
cin >> num;
PriorityQueueBST p;
for (int x = 0; x < num; x++)
{
cout << "Enter number " << x + 1
<< " of " << num << ": ";
cin >> input;
p.Enqueue(input);
}
for (int y = 0; y < num; y++)
{
cout << "Outputting number " << y + 1
<< " of " << num << ": ";
if(p.IsEmpty())
{
break; //we are done (this is an error!)
}
output = p.Dequeue();
cout << output << endl;
}
system("pause");
return 0;
//CTree* tr = new CTree();
//
//for (int i = 0; i < 3; i++)
// tr->Add();
//tr->View();
//system("pause");
//return 0;
}
BST Declaration file
//#ifndef CTREE_H
//#define CTREE_H
//using namespace std;
struct TreeNode
{
int info;
TreeNode* leftLink;
TreeNode* rightLink;
};
class CTree
{
private:
void AddItem( TreeNode*&, TreeNode*);
void DisplayTree(TreeNode*);
void Retrieve(TreeNode*&, TreeNode*,bool&);
void Destroy(TreeNode*&);
public:
CTree();
~CTree();
void Add();
void View();
bool IsEmpty();
int DeleteLargest(TreeNode*&);
TreeNode *tree;
};
//#endif
BST Implementation file
#include <iostream>
#include <string>
using namespace std;
#include "CTree.h"
CTree::CTree()
{
tree = NULL;
}
CTree::~CTree()
{
Destroy(tree);
}
void CTree::Destroy(TreeNode*& tree)
{
if (tree != NULL)
{
Destroy(tree->leftLink);
Destroy(tree->rightLink);
delete tree;
}
}
bool CTree::IsEmpty()
{
if(tree == NULL)
{
return true;
}
else
{
return false;
}
}
void CTree::Add()
{
TreeNode* newPerson = new TreeNode();
/*cout << "Enter the person's name: ";
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
cin.getline(newPerson->name, 20);*/
/* cout << "Enter the person's contribution: ";
cin >> newPerson->info;*/
/*bool found = false;*/
newPerson->leftLink = NULL;
newPerson->rightLink = NULL;
/*Retrieve(tree, newPerson, found);
if (found)
cout << "info allready entered\n";
else*/
AddItem(tree, newPerson);
}
void CTree::View()
{
if (IsEmpty())
{
cout<<"The list is empy";
}
else
{
DisplayTree(tree);
}
};
void CTree::AddItem( TreeNode*& ptr, TreeNode* newPer )
{
if (ptr == NULL)
{
ptr = newPer;
}
else if ( newPer->info < ptr->info)
AddItem(ptr->leftLink, newPer);
else
AddItem(ptr->rightLink, newPer);
}
void CTree::DisplayTree(TreeNode* ptr)
{
if (ptr == NULL)
return;
DisplayTree(ptr->rightLink);
cout << ptr->info << endl; //cout<<ptr->name<<" "<<"$"<<ptr->info <<endl;
DisplayTree(ptr->leftLink);
}
void CTree::Retrieve(TreeNode*& ptr, TreeNode* newPer, bool& found)
{
{
if (ptr == NULL)
{
found = false; // item is not found.
}
else if ( newPer->info < ptr->info)
{
Retrieve(ptr->leftLink, newPer, found);
}
// Search left subtree.
else if (newPer->info > ptr->info)
{
Retrieve(ptr->rightLink, newPer, found);// Search right subtree.
}
else
{
//newPer.info = ptr->info; // item is found.
found = true;
}
}
}
int CTree::DeleteLargest(TreeNode*& tr)
{
int largest = 0;;
TreeNode* prev;
TreeNode* cur;
prev = NULL;
cur = tr;
if (tr == NULL)
{
cout << "The tree is empty"<<endl;
}
else if (tr->rightLink == NULL)
{
largest = tr->info;
}
else
{
prev = tr;
tr = tr->rightLink;
DeleteLargest(tr);
}
return largest;
}
Priority Queue Declaration
//#include <iostream>
//using namespace std;
//#include "SortedLinkedList.h"
#ifndef PRIORITYQUEUESLL__H
#define PRIORITYQUEUESLL__H
class PriorityQueueBST
{
public:
PriorityQueueBST();
~PriorityQueueBST();
void Enqueue(int);
int Dequeue();
bool IsEmpty();
private:
CTree* ourTree;
//sslNode* head;
};
#endif
Priority Queue Implementation
#include <iostream>
using namespace std;
#include "CTree.h"
#include "PriorityQueueBST.h"
PriorityQueueBST::PriorityQueueBST()
{
ourTree = new CTree();
//head = NULL;
}
PriorityQueueBST::~PriorityQueueBST()
{
}
void PriorityQueueBST::Enqueue(int dataToEnter)
{
ourTree->Add();
}
int PriorityQueueBST::Dequeue()
{
//check for empty??
return ourTree->DeleteLargest(ourTree->tree);
}
bool PriorityQueueBST::IsEmpty()
{
return ourTree->IsEmpty();
}
Your output is always 0 because in
int CTree::DeleteLargest(TreeNode*& tr)
{
int largest = 0;;
TreeNode* prev;
TreeNode* cur;
prev = NULL;
cur = tr;
if (tr == NULL)
{
cout << "The tree is empty"<<endl;
}
else if (tr->rightLink == NULL)
{
largest = tr->info;
}
else
{
prev = tr;
tr = tr->rightLink;
DeleteLargest(tr);
}
return largest;
}
you only set largest to something potentially != 0 if tr->rightlink is NULL. Otherwise you recur and set the largest variable local to another invocation of the function. That change is lost when the recursion goes up again, and in the topmost invocation, largest is still 0.
In the last line of the else branch, you should either
largest = DeleteLargest(tr);
or
return DeleteLargest(tr);
Another problem is that, despite its name, deleteLargest doesn't actually delete anything, so with the above, you would still always get the same value.

Remove a data from a node

#include <conio.h>
#include <iostream>
#include <string>
using namespace std;
class MysticalBag
{
private:
int useCount;
int content;
string itemName;
public:
MysticalBag *next_ptr;
void setAttributes()
{
//Called for showing the items without any placement of item
useCount = 1;
content = 5;
itemName = "Healing Potion";
}
int takeUseCount()
{
return useCount;
}
int takeContent()
{
return content;
}
string takeItemName()
{
return itemName;
}
void setAttributes(int userCount, int content, string itemName)
{
this->useCount = useCount;
this->content = content;
this->itemName = itemName;
}
void itemAdder()
{
cout << "Enter use count (1-3) " <<endl;
cin >> useCount;
cout << "Enter content (1.0 - 100.0) " <<endl;
cin >> content;
cout << "Enter item name as text" << endl;
cin >> itemName;
cout<< itemName <<" is added in the bag."<< endl;
}
void showBag()
{
cout << "Showing bag contents" << endl << endl;
cout << itemName << endl;
cout << "U - "<< useCount <<", C - "<< content << endl;
}
};
int main()
{
char choice1,choice2;
choice1 = 0;
MysticalBag *head, *tail, *navigator;
navigator = new MysticalBag();
navigator->setAttributes();
head = navigator;
tail = navigator;
tail->next_ptr = NULL;
while(choice1 !='x')
{
cout << "What do you want to do with the bag?" << endl;
cout << "(a)dd item" << endl;
cout << "(r)emove item" << endl;
cout << "(s)how items" <<endl;
cout << "e(x)it" <<endl;
cin >> choice1;
if(choice1 == 'a')
{
navigator = new MysticalBag();
if(head==NULL)
{
head=navigator;
tail=navigator;
tail->next_ptr=NULL;
}
navigator->itemAdder();
tail->next_ptr = navigator;
tail = navigator;
tail->next_ptr = NULL;
}
else if(choice1 == 'r')
{
navigator = head;
tail = head;
while(navigator->next_ptr != NULL)
{
navigator = navigator->next_ptr;
tail = navigator;
}
cout << "Do you want to remove "<< navigator->takeItemName() <<" from your bag? (y/n)"<< endl;
cin >> choice2;
if(choice2 == 'y')
{
navigator = head;
if(navigator == head)
//I am stuck at this point!
navigator = NULL;
cout << "Item removed." << endl;
tail = head;
while(tail->next_ptr != NULL)
{
tail = tail->next_ptr;
}
}
else
{
cout<< "No item removed" <<endl;
}
navigator = head;
if(navigator == head && navigator == tail)
{
navigator = NULL;
head = NULL;
tail = NULL;
}
else
{
navigator = tail;
navigator = NULL;
tail = NULL;
tail = head;
while(tail->next_ptr != NULL)
{
tail = tail->next_ptr;
}
}
}
else if(choice1 != 'x')
{
navigator = head;
while(navigator != NULL)
{
navigator->showBag();
navigator = navigator->next_ptr;
}
}
}
getch();
}
My objective is removing data from a node.
the user can put in data in the node, which is the Navigator.
What I am thinking of is to point navigator to head and Making head recalling the setAttributes(). Which will show the "Healing potion". But, if the user adds to items. How would I remove just one item at a time?
Can you only remove the last item added to the bag, or can any item be removed? The more general case is asking about deletions from a linked list.
To remove an node (item) from a linked list(bag), you need to know the parent of the item you wish to remove. The parent of a node is the node who's next_ptr is the node. So in the loop, you need to track the parent of navigator:
while(navigator->next_ptr != NULL)
{
/* a sample list */
/* "parent" --> "navigator" --> "navigator->next_ptr" */
parent = navigator; /* now we know who points to navigator */
navigator = navigator->next_ptr;
tail = navigator;
}
Once we know the parent of navigator, all that needs to be done to remove navigator is:
parent->next_ptr = navigator->next_ptr;
/* now the list looks like */
/* "parent" --> "navigator->next_ptr" */
And now navigator is removed from the bag.
I think there are still issues with many of your while loops, but fixing them requires knowing more about your intentions.
Is this a list? Why don't you use std::list from inside your custom class?
Well, in short, what you're asking is 'How do a I access a class function if I have a pointer to a class member?' At least that's how I see it.
#include "Items.h" //let me assume you have some sort of struct or class for items in your bag
class Bag : public player { //player would give access to attributes like HP/MP/Who Owns the bag, etc..
protected:
vector<Item*> Contents;
int MaxItems;
public:
Bag();
Store(Item* It);
Remove(Item* It);
UseItem(Item* It);
};
Bag::Store(Item* It) {
if(Contents.size() >= MaxItems) return;
for( int i = 0; i < Contents.size(); i++ ) {
if(It == Contents[i] ) {
return;
}
}
Contents.push_back(It);
}
Bag::Remove(Item* It) {
for(int i = 0; i < Contents.size(); i++) {
if( It == Contents[i] ) {
Contents.erase(Contents.begin() + i);
break;
}
}
Bag::UseItem(Item* It) {
if(!(It->Usable())) { return };
It->Use();
}
class Item {
protected:
int ItemType; //suggest you use some enum for this
public:
Item();
virtual bool Usable();
virtual void Use();
};
Item::Item() { };
bool Item::Usable() {
//Purely Virtual
}
void Item::Use() {
//Same
}
class Potion : public Item {
protected:
int PotionType; //Again, I'd enum this
public:
Potion();
virtual bool Useable();
virtual void Use();
}
Potion::Potion() { ItemType = POTION; }
bool Potion::Useable() { return true; }
void Potion::Use() { //Purely Virtual }
class HealPotion : public Potion {
protected:
int Strength; //who knows, # of hp to heal
public:
HealPotion();
virtual void Use();
};
HealPotion::HealPotion() { PotionType = Heal; Strength = 45; }
void HealPotion::Use() { Owner->ChangeHits(Strength);
this->RemoveItem(this); } //Now you might also want to destroy the item to free up memory

what happen to my code?

I am new to C++. I am really confused between C and C++. I am familair with C and java, but not C++. Today I am going to write a linked list program using C++. But to what happened to my code ???
Thanks.
Raymond
the result:
Unhandled exception at 0x00412656 in 09550978d.exe: 0xC0000005: Access violation writing location 0xcdcdcdcd.
#include <iostream>
#include <string>
using namespace std;
struct word
{
bool empty;
string name;
int count;
word* next;
};
typedef struct word word;
word* create(word* theList)
{
word* head = (word*)malloc(sizeof(word));
head->empty = false;
head->name = "";
head->next = 0;
return head;
}
void print(word* theList)
{
word* current = theList;
while(current!=0)
{ cout << current->name << " : " << current->count << " \n" ;
current = current->next;
}
}
void add(string myString, word* theList)
{
//word* newWord = (word*)malloc(sizeof(word));
if( theList->empty == false )
{
theList->empty = true;
theList->name = myString;
theList->next = 0;
}
else
{
word* current = theList;
while(current->next!=0)
{
current = current->next;
}
word* newWord = (word*)malloc(sizeof(word));
newWord->empty = true;
newWord->name = myString;
newWord->next = 0;
current->next = newWord;
}
}
int main(void)
{
word* theList = 0;
theList = create(theList);
add("Hello", theList);
//add("world", theList);
}
#include <iostream>
#include <string>
using namespace std;
class word
{
public:
string name;
int count;
word *next;
word (string name);
};
word::word (string myName)
{
name = myName;
next = NULL;
count = 1;
}
class List
{
public:
bool isEmpty;
word* theHead;
List();
List(word* aHead);
void print();
void add(string myString);
void search(string myString);
};
List::List()
{
isEmpty = true;
}
List::List(word* aHead)
{
isEmpty = false;
theHead = aHead;
}
void List::add(string myString)
{
word* newWord = new word(myString);
if (isEmpty == true)
{
isEmpty = false;
theHead = newWord;
}
else
{
word* current = theHead;
if ( current->next == NULL)
{
if( myString.compare(current->name) == 0 )
{
current->count = current->count + 1;
return;
}
}
else
{
while ( current->next != NULL )
{
if( myString.compare(current->name) == 0 )
{
current->count = current->count + 1;
return;
}
current = current->next;
}
}
current->next = newWord;
}
}
void List::print ()
{
if (isEmpty)
{
cout << "nothing in the list";
}
else
{
word* current = theHead;
while(current != NULL)
{
cout << current->name << " : " << current->count << " \n" ;
current = current->next;
}
}
}
void List::search(string myString)
{
if (isEmpty)
{
cout << "The word : " << myString << " is not in the List.\n";
}
else
{
word* current = theHead;
while( current != NULL )
{
if( myString.compare(current->name) == 0 )
{
cout << "The word : " << myString << " is in the List.\n";
return;
}
else
{
current = current->next;
}
}
cout << "The word : " << myString << " is not in the List.\n";
}
return;
}
int main(void)
{
List theList = List();
string str1 = "Hello";
string str2 = "world";
theList.add(str1);
theList.add(str2);
theList.add(str1);
theList.search("Hello");
theList.search("You");
theList.print();
int i;
scanf("%d", &i);
}
You should be using the new operator instead of malloc. See the difference here. Also why use structs and typedefs when c++ allows you to make a class
Here is my version of your code, its not bug free yet but it should illustrate how to use new and classes. I will try to fix it fully and update you.
Also note that within the class structure of c++ you automatically get a this pointer with member functions that acts as a pointer to the class, so you no longer have to pass in word* theList
Edit: I updated with working code, the only thing that doesn't work is the count aspect to the list. Otherwise notice that there are two classes, List interfaces with word to create a linked list, I have not included any memory management aspects to the code (which would not be so hard using the c++ destructor, if you need such facilities please indicate so in the comments, and I will be sure to add.
#include <iostream>
#include <string>
using namespace std;
class word
{
public:
string name;
int count;
word *next;
word (string name);
};
word::word (string myName)
{
name = myName;
next = NULL;
count = 0;
}
class List
{
public:
bool isEmpty;
word* theHead;
List();
List(word* aHead);
void print();
void add(string myString);
};
List::List()
{
isEmpty = true;
}
List::List(word* aHead)
{
isEmpty = false;
theHead = aHead;
}
void List::add(string myString)
{
word* newWord = new word(myString);
if (isEmpty == true)
{
isEmpty = false;
theHead = newWord;
}
else
{
word* current = theHead;
while(current->next != NULL)
{
current = current->next;
}
current->next = newWord;
}
}
void List::print ()
{
if (isEmpty)
{
cout << "nothing in the list";
}
else
{
word* current = theHead;
while(current != NULL)
{
cout << current->name << " : " << current->count << " \n" ;
current = current->next;
}
}
}
int main(void)
{
List theList = List();
string str1 = "Hello";
string str2 = "world";
theList.add(str1);
theList.add(str2);
theList.print();
}
Edit: Here is the destructor to free the allocated memory, make sure to add the prototype ~List() in the class declaration:
List::~List()
{
if (!isEmpty)
{
word* prev = NULL;
word* current = theHead;
while(current != NULL)
{
prev = current;
current = current->next;
delete prev;
}
}
}
Hope this helps.
Most obvious problem: use new and not malloc to allocate new objects: malloc doesn't call constructor and one design principle of C++ is that constructors are called before any other operations on an object.
BTW, you code look like C using only the most basic C++ features. It would never be written like this by someone knowing C++ (word would have a constructor and private member, even for people using C++ as a "better C").
For one, in Add function
if( theList->empty == false )
{
theList->empty = true;
theList->name = myString;
theList->next = 0;
}
should be opposite - if list->empty == true, then set it to false.
As for the unhandled exception, a simple step by step 5 minute debugging session will both help you find your errors and will make you like and use the debugger. I mean it. DO TRY DEBUGGING!!!
my2c