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
Related
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?)
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)
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.
edit, I'll try to give a better exemple:
first I'll tell your about the program:
basicly, there' two phases, the first is inserting the words (works perfectly fine)
struct trieLeaf {
keyType age = 1;
};
class Trie
{
private:
dataType character;
trieLeaf *leaf = nullptr;
class Trie **alphabet = nullptr;
int main()
{
string input;
Trie dictionary('\0');
while (getline(cin, input) && input[0] != '.')
{
dictionary.analyzeText(input);
}
while (getline(cin, input) && input[0] != '.')
{
dictionary.approxFind(input);
}
system("pause>null");
}
second phase is searching for words, if words is found then I need to reduce the number of times it has been added by 1.
if number of times it has been added is 0, then I remove it.
void Trie::approxFind(string &word)
{
int index = 0;
string result;
Trie *curr;
if (curr=find(word))
{
cout << curr->leaf->age << endl;
curr->leaf->age -= 1;
if (curr->leaf->age == 0)
{
remove(word);
}
}
else
{
result = approximate(word);
cout << "Did you mean " << result << "?\n";
}
}
Trie* Trie::find(const string &word)
{
int index = 0;
Trie *curr = this;
while (word[index] != '\0')
{
if (curr->alphabet[word[index] - 'a'] != nullptr)
{
curr = curr->alphabet[word[index++] - 'a'];
}
else
{
return (nullptr);
}
}
if (curr->leaf != nullptr)
{
return (curr);
}
}
void Trie::remove(const string &word)
{
int index = 0;
Trie *curr = this, **tempArr, *temp;
while (word[index] != '\0')
{
tempArr = curr->alphabet;
temp = curr;
curr = curr->alphabet[word[++index] - 'a'];
if (!isArrEmpty(tempArr))
{
delete(tempArr);
}
delete(temp);
temp = nullptr;
}
}
bool Trie::isArrEmpty(Trie **alphabet)
{
for (int index = 0; index < 26; index++)
{
if (!alphabet[index])
{
return (true);
}
}
return(false);
}
TempArr in isArrEmpty is losing the object it's pointing to when passing onto the funcion.
I hope it gives a better idea why
Basically I'm trying to get this function to work, its functionally a linked list but with node named ticket. Getting an error "head is nullptr" even though its outputting that ive assigned head (cout statements were called).
Anyways here is my flight.cpp
Flight::Flight() {
head = NULL;
}
Flight::Flight(ticket* input) {
head = input;
}
void Flight::printTicket() {
ticket* iterator = head;
while (iterator->next != NULL) {
std::cout << iterator->name << std::endl;
}
}
//00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
ticket* Flight::findSpot(ticket* t) { //returns the ticket before where the new ticket needs to be inserted
std::string name = t->name;
ticket* iterator = head;
while (iterator->next != NULL) {
if (isBefore(iterator->name, name)) {
iterator = iterator->next;
}
return iterator;
}
std::cout << "\nFIND SPOT DID NOT WORK\n";
return t;
}
void Flight::addTicket(std::string inName) {
std::cout << "4 ";
ticket *tmp = ( inName, NULL);
std::cout << "5 ";
if (head == NULL) {
std::cout << "1, ";
head = tmp;
}
else {
std::cout << "2, ";
ticket* after = findSpot(tmp);
ticket* before = after->next;
after->next = tmp;
tmp->next = before;
}
}
//00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
std::string Flight::tolowercase(std::string input) {
for (int i = 0; i < input.length(); i++) {
if (input[i] < 97) {
input[i] = (input[i] + 32);
}
}
return input;
}
bool Flight::isBefore(std::string input1, std::string input2) {
input1 = tolowercase(input1);
input2 = tolowercase(input2);
for (int i = 0; (i < input1.size() && i < input2.size()); i++) {
if (input1[i] < input2[i]) return true;
else if (input2[i] < input1[i]) return false;
}
std::cout << "ISBEFORE IS BROKEN";
return false;
}
Flight.h
struct ticket {
std::string name = "";
ticket *next = NULL;
};
class Flight {
private:
ticket* head;
ticket* findSpot(ticket* t);
//converts strings to lower case to allow better comparing
std::string tolowercase(std::string input);
bool isBefore(std::string input1, std::string input2);
public:
Flight();
Flight(ticket * input);
void printTicket();
void addTicket(std::string inName);
};
And my source.cpp
int main() {
std::cout << "Hey!";
Flight james = Flight();
std::cout << "Hahaha!";
std::string jaaems = "Jaems";
james.addTicket(jaaems);
james.addTicket("hahahaha");
james.addTicket("hopefullythisworks");
std::cout << "Made it!";
james.printTicket();
return 0;
}
Does anyone have any insight on this? Ive been ripping my hair out over this and am at the end of my wits as to why its null. I could not find an answer that I understood in any other threads, and this is my last resort. If anyone can help I would be eternally grateful.
Proper way to initialize ticket is:
ticket *tmp = new ticket(inName, NULL);
or
ticket tmp = ticket(inName, NULL);
head = &tmp;
Update:
And you need to change your ticket declaration to include constructor:
struct ticket {
std::string name;
ticket *next;
ticket(std::string aname, ticket *anext) {
name = aname;
next = anext;
}
};
or if you do not want to add constructor, just initialize it like this:
ticket tmp = {inName, NULL};
head = &tmp;