C++ Program Compiler Error: No Matching Function - c++

I'm using a linked list to implement a concordance program. I am getting the following compiler error when trying to compile the program with g++:
concordancetest.cpp: In function 'void build_list(std::ifstream&, char*)':
concordancetest.cpp:65: error: no matching function for call to ‘Concordance::insert(char*&, int&)'
concordance.h:22: note: candidates are: void Concordance::insert(char (&)[9], int&)
Below is the code I have written:
Header File:
#ifndef CONCORDANCE_H
#define CONCORDANCE_H
#include <iostream>
#include <cstdlib>
const int MAX = 8;
class Concordance
{
public:
//typedef
typedef char Word[MAX+1];
//constructor
Concordance();
//destructor
~Concordance();
//modification member functions
void insert(Word& word, int& n);
void remove(Word& word);
int get_count(Word& word);
//constant member functions
int length() const;
//friend member functions
friend std::ostream& operator << (std::ostream& out_s, Concordance& c);
private:
struct Node
{
Word wd;
int count;
Node *next;
};
Node *first;
Node* get_node(Word& word, int& count, Node* link);
};
#endif
Implementation Code:
//class definition
#include "concordance.h"
#include <iostream>
#include <cstring>
#include <iomanip>
using namespace std;
Concordance::Concordance()
{
first = NULL;
}
Concordance::~Concordance()
{
Node *temp;
while(first != NULL)
{
temp = first;
first = first -> next;
delete temp;
}
}
void Concordance::insert(Word& word, int& n)
{
Node *prev;
if(first == NULL || strcmp(first -> wd, word) > 0)
first = get_node(word, n, first);
else
{
prev = first;
while(prev -> next != NULL && strcmp(prev -> next -> wd, word) > 0)
prev = prev -> next;
prev -> next = get_node(word, n, prev -> next);
}
}
void Concordance::remove(Word& word)
{
Node *prev, *temp;
prev = temp;
if(prev -> wd == word)
{
first = first -> next;
delete prev;
}
else
{
while(strcmp(prev -> next -> wd, word) > 0)
prev = prev -> next;
temp = prev -> next;
prev -> next = temp -> next;
delete temp;
}
}
int Concordance::get_count(Word& word)
{
while(strcmp(first -> wd, word) != 0)
first = first -> next;
return first -> count;
}
int Concordance::length() const
{
Node *cursor;
int len;
len = 0;
for(cursor = first; cursor != NULL; cursor = cursor -> next )
len++;
return len;
}
Concordance::Node* Concordance::get_node (Word& word, int& count, Node* link)
{
Node *temp;
temp = new Node;
strcpy(temp-> wd, word);
temp-> next = link;
temp -> count = count+1;
return temp;
}
ostream& operator << (ostream& out_s, Concordance& c)
{
Concordance::Node *cursor;
out_s << "Word" << setw(10) << " " << "Count" << endl;
out_s << "--------------------" << endl;
for(cursor = c.first; cursor != NULL && cursor->next != NULL; cursor = cursor-> next )
out_s << cursor-> wd << setw(10) << " " << cursor -> count << endl;
if(cursor != NULL)
out_s << cursor-> wd << setw(10) << " " << cursor -> count << endl;
out_s << "--------------------" << endl;
return out_s;
}
Test Program:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
#include "concordance.h"
using namespace std;
void read_word(ifstream& in_file, char array[]);
void build_list(ifstream& in_file, char array[]);
int main()
{
char file_name[100];
ifstream in_file;
char array[MAX+1];
cout << "Enter a file name: ";
cin >> file_name;
in_file.open(file_name);
build_list(in_file, array);
in_file.close();
return EXIT_SUCCESS;
}
void read_word(ifstream& in_file, char array[])
{
char ch;
int i = 0;
in_file.get(ch);
while(isalpha(ch) && !isspace(ch))
{
if(i > MAX-1)
{
while(!isspace(ch))
in_file.get(ch);
break;
}
ch = tolower(ch);
array[i] = ch;
i++;
in_file.get(ch);
}
for(int j = 0; j < i; j++)
cout << array[j];
cout << endl;
}
void build_list(ifstream& in_file, char array[])
{
Concordance c;
int count = 0;
while(!in_file.eof())
{
read_word(in_file, array);
c.insert(array, count);
}
cout << c;
}

The type of char array[] is char *, so when it looks for a matching function, none is found. You can fix this by using typedef char* Word; and enforcing your max length inside the functions that require it.

Related

How to return the values of the char linked lists and store it as a string?

I created this program that should check the string entered by user in form of characters using doubly linked lists in C++, however I got stuck at the last point in which I should compare the original word with the reversed one to see if the two words are palindrome or not, how to store the content of function display() and reverse() to a string variable so that I can return the value and compare them?
Also, reverse() function doesn't display the reversed word
This is my code:
#include <iostream>
using namespace std;
class Storage {
public:
char lett;
Storage* next;
Storage* prev;
};
void push(char lett1, Storage** head) {
Storage* n = new Storage();
n->lett = lett1;
n->next = NULL;
if (*head == NULL) {
*head = n;
}
else {
n->next = *head;
*head = n;
}
}
void display(Storage* head, int no) {
Storage* s = head;
while (head != NULL) {
int i = 0;
cout << head->lett;
s = head;
head = head->next;
}
}
void reverse(Storage* tail) {
Storage* t = tail;
// Storage* original= tail;
while (t != NULL) {
cout << t->lett;
t = t->prev;
}
}
/*
string checkPalindrome() {
string check;
if ()
check == "Yes";
else
check == "No";
return check;
}
*/
int main() {
Storage* head = NULL; Storage* tail = NULL;;
char lett;
int size;
string result;
cout << ":: Palindrome Program ::\n" << endl;
cout << "Enter total character: ";
cin >> size;
cout << "Enter character: ";
for (int i=0; i < size; i++) {
cin >> lett;
push(lett, &head);
}
cout << "Your word: ";
display(head, size); //compare content of this
cout << "\nReversed word: ";
reverse(tail); // with this
/*
result = checkPalindrome();
cout << "Palindrome: " << result << endl;
*/
return 0;
}
You have some bugs in your code. First of all my tip is that you need to make a class/struct which will hold the head and tail of your list. For example:
class DLList{
public:
NODE *head;
NODE *tail;
};
Also, as you can see you should have a class for your list nodes, and every node should have a pointer to the next node, and to the node before. Don't forget to make the first node previous pointer to point to NULL, and also the last nodes next pointer. Some other things I noticed is that you forgot to deallocate the dynamic/heap memory. Fix that with using 'free' or consider using smart pointers, so you don't have any memory leaks. At the end, try to avoid using namespace std;. It is considered a bad habit, due to bad performance. Hope it helped you. Here is the not optimized code snippet.
#include <iostream>
using namespace std;
class Storage {
public:
char lett;
Storage* next;
Storage* prev;
};
void push(char lett1, Storage** head, Storage **tail) {
Storage* n = new Storage();
n->lett = lett1;
n->next = NULL;
n->prev = NULL;
if (*head == NULL) {
*head = n;
*tail = n;
}
else {
n->next = *head;
(* head)->prev = n;
*head = n;
}
}
std::string display(Storage* head) {
Storage* s = head;
std::string org = "";
while (s != NULL) {
org += s->lett;
s = s->next;
}
return org;
}
std::string reverse(Storage* tail) {
Storage* t = tail;
std::string rev = "";
// Storage* original= tail;
while (t != NULL) {
rev += t->lett;
t = t->prev;
}
return rev;
}
bool checkPalindrome(Storage* head, Storage* tail) {
return display(head) == reverse(tail);
}
int main() {
Storage* head = NULL; Storage* tail = NULL;;
char lett;
int size;
cout << ":: Palindrome Program ::\n" << endl;
cout << "Enter total character: ";
cin >> size;
cout << "Enter character: ";
for (int i = 0; i < size; i++) {
cin >> lett;
push(lett, &head,&tail);
}
cout << "Your word: ";
cout<<display(head)<<endl; //compare content of this
cout << "\nReversed word: ";
cout<<reverse(tail)<<endl; // with this
cout << "\nPalindrome: " << checkPalindrome(head, tail) << endl;
return 0;
}
If you want to build a string with the characters in the linked list, you can use the std::string::operator+= to concatenate the single characters together.
For instance, considering your display function:
void display(Storage* head, int no) {
Storage* s = head;
while (head != NULL) {
int i = 0;
cout << head->lett;
s = head;
head = head->next;
}
}
instead of using cout << head->lett to print a single character, just concatenate that character to the result string using string::operator+=:
// Assume: std::string result
result += head->lett;
You could write a function that takes the linked list of characters as input, and returns a std::string, along these lines:
std::string ToString(const Storage* head) {
std::string result;
// For each node in the linked list
while (...) {
// Append current node's character to the result string
result += currentNode->lett;
}
return result;
}

My code exited after I filled up the priority queue

The code is about Huffman code.
I typed in "6 a 16 b 5 c 12 d 17 e 10 f 25", to fill in the priority_queue and the program exited without an error.
The priority queue is used to set up a binary search tree for decoding.
I made a function storeBinayNumber() to store the code for each character into an unordered map
called HuffmanCode , which is used for encoding;
and two function encocde() and decode() to encode or decode the string that will be later typed in .
What might be the problem ?
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
using namespace std;
class Node
{
public:
char ch = '\0';
int freq = 0;
Node *left;
Node *right;
};
void storeBinaryNumber(Node *root, unordered_map<char, string> &HuffmanCode, string str = '\0')
{
if (root = nullptr)
return;
if (!root->left && !root->right)
HuffmanCode[root->ch] = str;
storeBinaryNumber(root->left, HuffmanCode, str + "0");
storeBinaryNumber(root->right, HuffmanCode, str + "1");
}
void decode(Node *root, Node *current, string str, int index = 0)
{
if (index > str.length() - 1)
{
if (current == root)
{
cout << "Decoding suceeded" << endl;
return;
}
else
cout << "Invalid code" << endl;
return;
}
if (!current->left && !current->right)
{
cout << current->ch;
decode(root, root, str, index + 1);
}
else if (str[index] == '0')
{
decode(root, current->left, str, index + 1);
}
else if (str[index] == '1')
{
decode(root, current->right, str, index + 1);
}
}
void encode(string str, unordered_map<char, string> HuffmanCode)
{
for (int i = 0; i < str.length(); i++)
{
cout << HuffmanCode[str[i]];
}
}
int main()
{
int num;
cin >> num; //6 a 16 b 5 c 12 d 17 e 10 f 25
auto compare = [](Node *a, Node *b) //lambda expression
{ return a->freq > b->freq; };
priority_queue<Node *, vector<Node *>, decltype(compare)> q(compare);
unordered_map<char, string> HuffmanCode;
char character;
int frequency;
for (int i = 1; i <= num; i++)
{
cin >> character >> frequency;
Node *node = new Node;
node->ch = character;
node->freq = frequency;
node->left = nullptr;
node->right = nullptr;
q.push(node);
}
Node *root;
while (q.size() > 1)
{
Node *A = q.top();
q.pop();
Node *B = q.top();
q.pop();
Node *C = new Node;
C->left = A;
C->right = B;
C->freq = A->freq + B->freq;
if (q.empty())
root = C;
q.push(C);
}
storeBinaryNumber(root, HuffmanCode);
int en_or_de;
string input;
cout << "press 1 to encode , press 2 to decode." << endl;
cin >> en_or_de;
cout << "input: " << endl;
cin >> input;
if (en_or_de == 1)
{
encode(input, HuffmanCode);
}
else
decode(root, root, input);
system("pause");
return 0;
}
The code have several bugs:
Assign char type to string won't compile on my compiler
void storeBinaryNumber(Node *root, unordered_map<char, string> &HuffmanCode, string str = '\0')
The comparison should use ==, this seems to be a typo.
if (root = nullptr)
And the Node type missed destructor, which needs to a memory leak. After my fix the code seems to work. But it may still have logic bugs.
#include <iostream>
#include <queue>
#include <unordered_map>
#include <vector>
using namespace std;
class Node {
public:
char ch = '\0';
int freq = 0;
~Node() {
delete left;
delete right;
}
Node *left;
Node *right;
};
void storeBinaryNumber(Node *root, unordered_map<char, string> &HuffmanCode,
string str = "") {
if (root == nullptr) return;
if (!root->left && !root->right) HuffmanCode[root->ch] = str;
storeBinaryNumber(root->left, HuffmanCode, str + "0");
storeBinaryNumber(root->right, HuffmanCode, str + "1");
}
void decode(Node *root, Node *current, string str, int index = 0) {
if (index > str.length() - 1) {
if (current == root) {
cout << "Decoding suceeded" << endl;
return;
}
else
cout << "Invalid code" << endl;
return;
}
if (!current->left && !current->right) {
cout << current->ch;
decode(root, root, str, index + 1);
}
else if (str[index] == '0') {
decode(root, current->left, str, index + 1);
}
else if (str[index] == '1') {
decode(root, current->right, str, index + 1);
}
}
void encode(string str, unordered_map<char, string> HuffmanCode) {
for (int i = 0; i < str.length(); i++) {
cout << HuffmanCode[str[i]];
}
std::cout << std::endl;
}
int main() {
int num;
cin >> num; // 6 a 16 b 5 c 12 d 17 e 10 f 25
auto compare = [](Node *a, Node *b) // lambda expression
{ return a->freq > b->freq; };
priority_queue<Node *, vector<Node *>, decltype(compare)> q(compare);
unordered_map<char, string> HuffmanCode;
char character;
int frequency;
for (int i = 1; i <= num; i++) {
cin >> character >> frequency;
Node *node = new Node;
node->ch = character;
node->freq = frequency;
node->left = nullptr;
node->right = nullptr;
q.push(node);
}
Node *root;
while (q.size() > 1) {
Node *A = q.top();
q.pop();
Node *B = q.top();
q.pop();
Node *C = new Node;
C->left = A;
C->right = B;
C->freq = A->freq + B->freq;
if (q.empty()) root = C;
q.push(C);
}
storeBinaryNumber(root, HuffmanCode);
int en_or_de;
string input;
cout << "press 1 to encode , press 2 to decode." << endl;
cin >> en_or_de;
cout << "input: " << endl;
cin >> input;
if (en_or_de == 1) {
encode(input, HuffmanCode);
}
else
decode(root, root, input);
delete root;
// system("pause");
return 0;
}

Show full line of a CSV file C++

I am making a program that reads a .CSV file and loads it into binary search trees to sort its content, since I managed to load the .CSV and implement the tree however the content of the file is:
1, Peter, 230151515
5, Merrick, 25551561
7, Lucky, 4301616199
2, luis, 2589191919
16, Alfredo, 25891919
8, Linda, 129616919
I am using the first data of each row as a key and with the code that I carry, it orders it correctly, however I want it to show the rest of the row, not just the key, someone could tell me how I could do that, to show all the data of each key ordered.
output:
1
2
5
7
8
16
What I want to print would be something like:
1 Peter 230151515
2 Luis 2589191919
5 Merrick 25551561
7 Lucky 4301616199
8 Linda 129616919
16 Alfredo 25891919
Someone to help me correct my mistake please.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <sstream>
#include <vector>
#include<stdio.h>
#include<stdlib.h>
using namespace std;
struct node {
int key;
string name;
int num;
struct node *left, *right;
};
vector<node> persons;
struct node *newNode(int item)
{
struct node *temp = (struct node *)malloc(sizeof(struct node));
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
void inorder(struct node *root)
{
if (root != NULL)
{
//cout<<"\t";
inorder(root->left);
printf("\t%d\n", root->key);
inorder(root->right);
}
}
struct node* insert(struct node* node, int key)
{
/* If the tree is empty, return a new node */
if (node == NULL) return newNode(key);
/* Otherwise, recur down the tree */
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
/* return the (unchanged) node pointer */
return node;
}
struct node * minValueNode(struct node* node)
{
struct node* current = node;
/* loop down to find the leftmost leaf */
while (current && current->left != NULL)
current = current->left;
return current;
}
int main()
{
struct node *root = NULL;
ifstream fin("data.txt");
if (!fin)
{
cout << "File not open\n";
return 1;
}
string line;
const char delim = ',';
while (getline(fin, line))
{
istringstream ss(line);
node person;
ss >> person.key; ss.ignore(10, delim);
getline(ss, person.name,delim);
ss >> person.num;
if (ss)
persons.push_back(person);
}
for (unsigned int i=0; i< persons.size(); i++)
{
cout << setw(5) << persons[i].key<< setw(20) << persons[i].name<< setw(15) << persons[i].num << '\n';
root = insert(root, persons[i].key);
insert(root, persons[i].key);
}
cout << "\n\nInorder:\n";
// cout<<node.name;
inorder(root);
/*/cout<<"\nDelete 50\n";
root = deleteNode(root, 50);
cout<<"Inorder traversal of the modified tree \n";
inorder(root);/*/
/*
insert(root, 80);*/
return 0;
}
When you are printing out the key, you can also print out the other information of each node. Here's a solution using cout:
void inorder(struct node *root)
{
if (root != NULL)
{
inorder(root->left);
std::cout << root->key << " " << root->name << " " << root->num << "\n";
inorder(root->right);
}
}
There were some main problems and some other problems. The main problems were that you didn't store and print all data. I did the following:
Clean up includes
Remove using namespace std;
Rename struct node to Node
Add a struct for Person next to the struct for Node
Add a constructor for Person to Node
Make insert a method
Use smart pointers. One problem of dynamic memory allocation is that you have to clean up but you didn't
#include <iostream>
#include <iomanip>
#include <fstream>
#include <memory>
#include <string>
#include <sstream>
#include <vector>
struct Person {
int key;
std::string name;
int num;
};
struct Node : Person {
Node(const Person &person) : Person(person) {}
std::unique_ptr<Node> left, right;
void insert(const Person &person);
};
void Node::insert(const Person &person) {
/* recur down the tree */
if (key > person.key) {
if (left)
left->insert(person);
else
left = std::make_unique<Node>(person);
} else if (key < person.key) {
if (right)
right->insert(person);
else
right = std::make_unique<Node>(person);
}
}
std::vector<Person> persons;
void inorder(Node *root) {
if (root) {
// cout<<"\t";
inorder(root->left.get());
std::cout << '\t' << root->key << ' ' << root->name << ' ' << root->num << '\n';
inorder(root->right.get());
}
}
Node *minValueNode(Node *node) {
Node *current = node;
/* loop down to find the leftmost leaf */
while (current && current->left) current = current->left.get();
return current;
}
int main() {
std::unique_ptr<Node> root;
std::ifstream fin("data.txt");
if (!fin) {
std::cout << "File not open\n";
return 1;
}
std::string line;
const char delim = ',';
while (std::getline(fin, line)) {
std::istringstream ss(line);
Person person;
ss >> person.key;
ss.ignore(10, delim);
std::getline(ss, person.name, delim);
ss >> person.num;
if (ss) persons.push_back(person);
}
for (unsigned int i = 0; i < persons.size(); i++) {
std::cout << std::setw(5) << persons[i].key << std::setw(20)
<< persons[i].name << std::setw(15) << persons[i].num << '\n';
if (!root) root = std::make_unique<Node>(persons[i]);
else root->insert(persons[i]);
}
std::cout << "\n\nInorder:\n";
// cout<<node.name;
inorder(root.get());
/*/cout<<"\nDelete 50\n";
root = deleteNode(root, 50);
cout<<"Inorder traversal of the modified tree \n";
inorder(root);/*/
/*
insert(root, 80);*/
return 0;
}

C++ linked list with an object class

I am trying to implement a linked list with an object class. The following is my implementation.
Prof header file:
#ifndef PROF_H
#define PROF_H
#include <iostream>
#include <string>
using namespace std;
class Prof
{
public:
string first_name;
string last_name;
int room_number;
string phone_number;
};
#endif /* PROF_H */
LinkedList header file:
#ifndef LinkedList_h
#define LinkedList_h
#include <iostream>
#include <string>
#include "Prof.h"
using namespace std;
struct Node {
Prof prof;
Node *next;
};
class LinkedList{
private:
Node * head;
int length;
// public members
public:
// Default Constructor
LinkedList();
bool insertProfessor( Node * newNode, int position );
bool removeProfessor( int position );
void printProfessors();
void sortProfessors();
void searchProfessors(string name);
bool insert( Node * newNode);
// Destructor
~LinkedList();
};
#endif
LinkedList class:
#include "LinkedList.h"
#include "Prof.h"
// Default Constructor creates the head node.
LinkedList::LinkedList()
{
head -> prof;
head -> next=NULL;
length = 0;
}
bool LinkedList::insertProfessor( Node * newNode, int position )
{
if ((position <= 0) || (position > length + 1))
{
cout << "Error: No such position\n";
return false;
}
if (head -> next == NULL)
{
head -> next = newNode;
length++;
return true;
}
int count = 0;
Node * p = head;
Node * q = head;
while (q)
{
if (count == position)
{
p -> next = newNode;
newNode -> next = q;
length++;
return true;
}
p = q;
q = p -> next;
count++;
}
if (count == position)
{
p -> next = newNode;
newNode -> next = q;
length++;
return true;
}
cout << "Error: The professor was not added to the list.\n";
return false;
}
void LinkedList::sortProfessors()
{
Node * p = head;
Node * q = head;
Node * k = head;
Node * m = head;
int count = 0;
while(count<length){
while (q)
{
p = q;
k = p -> next;
m = k -> next;
if(p -> prof.first_name > k->prof.first_name){
p->next = m;
k->next = p;
} else if(p -> prof.first_name == k->prof.first_name){
if(p -> prof.last_name > k->prof.last_name){
p->next = m;
k->next = p;
}
}
q = p -> next;
}
count++;
}
}
void LinkedList::searchProfessors(string name){
bool found;
Node * p = head;
Node * q = head;
cout << "Professors";
cout << "\n---------------------------\n";
while (!found)
{
p = q;
if((p->prof.first_name==name) || (p->prof.last_name==name)){
cout << "Found!!\n"<< endl;
cout << "\t" << p -> prof.first_name<<" "<<p -> prof.last_name << endl;
cout << "\tPhone number: " << p -> prof.phone_number << endl;
cout << "\tRoom Number: "<< p -> prof.room_number << endl;
cout << "\n";
found = true;
}
q = p -> next;
}
}
bool LinkedList::removeProfessor( int position )
{
if ((position <= 0) || (position > length + 1))
{
cout << "Error: No such position.\n";
return false;
}
if (head -> next == NULL)
{
cout << "Error: The list is empty.\n";
return false;
}
int count = 0;
Node * p = head;
Node * q = head;
while (q)
{
if (count == position)
{
p -> next = q -> next;
delete q;
length--;
return true;
}
p = q;
q = p -> next;
count++;
}
cout << "nError: No one was removed.\n";
return false;
}
void LinkedList::printProfessors()
{
Node * p = head;
Node * q = head;
cout << "Professors";
cout << "\n---------------------------\n";
while (q)
{
p = q;
cout << "\t" << p -> prof.first_name<<" "<<p -> prof.last_name << endl;
cout << "\tPhone number: " << p -> prof.phone_number << endl;
cout << "\tRoom Number: "<< p -> prof.room_number << endl;
cout << "\n"<<endl;
q = p -> next;
}
}
bool LinkedList::insert( Node * newNode){
while(false){
if (head -> next == NULL)
{
head -> next = newNode;
length++;
return true;
} else {
Node * next = head -> next;
head=next;
false;
}
}
}
LinkedList::~LinkedList()
{
Node * p = head;
Node * q = head;
while (q)
{
p = q;
q = p -> next;
if (q) delete p;
}
}
main file:
#include <cstdlib>
#include <string>
#include <iostream>
#include "LinkedList.h"
#include "Prof.h"
using namespace std;
LinkedList professorsList;
int main()
{
LinkedList professorsList;
int choice=0;
cout<<"Please select your choice.\n 1. Insert.\n 2.Search.\n 3.Delete.\n 4.Exit."<<endl;
cin >> choice;
string keyword="";
int position;
switch(choice){
case 1:
cout<<"Please select you source of input.\n 1.Console.\n 2.File.\n";
cin >> choice;
break;
case 2:
cout<<"Please the name you would like to search.\n";
cin >> keyword;
professorsList.searchProfessors(keyword);
break;
case 3:
cout<<"Please the position of the professor you would like to delete.\n";
cin >> position;
professorsList.removeProfessor(position);
return 0;
break;
case 4:
exit(0);
return 0;
break;
}
return 0;
}
void getInput(int choice){
string first_name;
string last_name;
string phonenumber;
int room_number;
string filename;
Node * professor = new Node;
switch(choice){
case 1:
cout<<"Please enter the professor's first name.\n";
cin >> first_name;
cout<<"Please enter the professor's last name.\n";
cin >> last_name;
cout<<"Please enter the professor's phone number.\n";
cin >> phonenumber;
cout<<"Please enter the professor's room number.\n";
cin >> room_number;
professor->prof.first_name = first_name;
professor->prof.last_name = last_name;
professor->prof.phone_number = phonenumber;
professor->prof.room_number = room_number;
professorsList.insert(professor);
break;
case 2:
cout<< "Enter the file name.\n"<<endl;
cin>>filename;
break;
}
}
When I try to run the program, I get the following error.
RUN FINISHED; Segmentation fault; core dumped; real time: 170ms; user: 0ms; system: 0ms
Please help me solve that error.

c++ Stuck making an binary tree implementation with an array and lists

I am working on writing a list of children binary tree implementation. In my code I have an array of lists. Each list contains a node followed by its children on the tree. I finished writing the code and everything compiled, but I keep getting a segmentation fault error and I cannot figure out why. I have been attempting to debug and figure out where my code messes up. I know that there is an issue with the FIRST function. It causes a segmentation fault. Also, when I try to print just one of the lists of the array, it prints everything. I have been stuck on this for a very long time now and would like some help. Can anyone offer suggestions as to why the FIRST and PRINT functions are not working? Maybe there is a large error that I just cannot see.
My code is as follows:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <array>
#include <string.h>
using namespace std;
struct node
{
char element;
struct node *next;
}*start;
class list
{
public:
void ADD(char n);
node* CREATE(char n);
void BEGIN(char n);
char FIRST();
char END();
char NEXT(char n);
char PREVIOUS(char n);
int LOCATE(char n);
void EMPTY();
void PRINT();
list()
{
start = NULL;
}
};
char PARENT(const char n, list tree[], int length)
{
int i=0;
list l;
for (i; i<length; i++)
{
l = tree[i];
if (n != l.FIRST())
{
if (l.LOCATE(n)>0)
return l.FIRST();
}
}
}
char LEFTMOST_CHILD(char n, list tree[], int length)
{
int i;
list l;
for (i=0; i<length; i++)
{
l = tree[i];
if (l.FIRST() == n)
return l.NEXT(n);
}
}
char RIGHT_SIBLING(char n, list tree[], int length)
{
int i;
list l;
for (i=0; i<length; i++)
{
l = tree[i];
if(n != l.FIRST())
{
if (l.LOCATE(n) > 0)
{
return l.NEXT(n);
}
}
}
}
char ROOT(list tree[]) //assumes array is in order, root is first item
{
list l;
l = tree[0];
cout << "Assigned tree to l" << endl;
return l.FIRST();
}
void MAKENULL(list tree[], int length)
{
int i;
list l;
for (i=0; i<length; i++)
{
l = tree[i];
l.EMPTY();
}
}
void list::PRINT()
{
struct node *temp;
if (start == NULL)
{
cout << "The list is empty" << endl;
return;
}
temp = start;
cout << "The list is: " << endl;
while (temp != NULL)
{
cout << temp->element << "->" ;
temp = temp->next;
}
cout << "NULL" << endl << endl;
}
void list::EMPTY()
{
struct node *s, *n;
s = start;
while (s != NULL)
{
n = s->next;
free(s);
s = n;
}
start = NULL;
}
int list::LOCATE(char n)
{
int pos = 0;
bool flag = false;
struct node *s;
s = start;
while (s != NULL)
{
pos++;
if (s->element == n)
{
flag == true;
return pos;
}
s = s->next;
}
if (!flag)
return -1;
}
void list::ADD(char n)
{
struct node *temp, *s;
temp = CREATE(n);
s = start;
while (s->next != NULL)
s = s->next;
temp->next = NULL;
s->next = temp;
}
node *list::CREATE(char n)
{
struct node *temp;
temp = new(struct node);
temp->element = n;
temp->next = NULL;
return temp;
}
void list::BEGIN(char n)
{
struct node *temp, *p;
temp = CREATE(n);
if (start == NULL)
{
start = temp;
start->next = NULL;
}
}
char list::FIRST()
{
char n;
struct node *s;
s = start;
cout << "s = start" << endl;
n = s->element;
cout << "n" << endl;
return n;
}
char list::END()
{
struct node *s;
s = start;
int n;
while (s != NULL)
{
n = s->element;
s = s->next;
}
return n;
}
char list::NEXT(char n)
{
char next;
struct node *s;
s = start;
while (s != NULL)
{
if (s->element == n)
break;
s = s->next;
}
s = s->next;
next = s->element;
return next;
}
char list::PREVIOUS(char n)
{
char previous;
struct node *s;
s = start;
while (s != NULL)
{
previous = s->element;
s = s->next;
if (s->element == n)
break;
}
return previous;
}
main()
{
list a,b,c,d,e,f,g,h,i,j,k,l,m,n;
a.BEGIN('A');
b.BEGIN('B');
c.BEGIN('C');
d.BEGIN('D');
e.BEGIN('E');
f.BEGIN('F');
g.BEGIN('G');
h.BEGIN('H');
i.BEGIN('I');
j.BEGIN('J');
k.BEGIN('K');
l.BEGIN('L');
m.BEGIN('M');
n.BEGIN('N');
a.ADD('B');
a.ADD('C');
b.ADD('D');
b.ADD('E');
e.ADD('I');
i.ADD('M');
i.ADD('N');
c.ADD('F');
c.ADD('G');
c.ADD('H');
g.ADD('J');
g.ADD('K');
h.ADD('L');
a.PRINT();
list tree[] = {a,b,c,d,e,f,g,h,i,j,k,l,m,n};
int length = sizeof(tree)/sizeof(char);
char root = ROOT(tree);
cout << "Found root" << endl;
char parent = PARENT('G', tree, length);
cout << "Found Parent" << endl;
char leftChild = LEFTMOST_CHILD('C', tree, length);
cout << "found left child" << endl;
char rightSibling = RIGHT_SIBLING('D', tree, length);
cout << "found right sibling" << endl;
cout << "The root of the tree is: ";
cout << root << endl;
cout << "The parent of G is: ";
cout << parent << endl;
cout << "The leftmost child of C is" ;
cout << leftChild << endl;
cout << "The right sibling of D is: " ;
cout << rightSibling << endl;
}
Any help will be very appreciated. Thanks you!
The fundamental problem is that you have written a lot of code before testing any of it. When you write code, start with something small and simple that works perfectly, add complexity a little at a time, test at every step, and never add to code that doesn't work.
The specific problem (or at least one fatal problem) is here:
struct node
{
char element;
struct node *next;
}*start;
class list
{
public:
//...
list()
{
start = NULL;
}
};
The variable start is a global variable. The class list has no member variables, but uses the global variable. It sets start to NULL every time a list is constructed, and every list messes with the same pointer. The function FIRST dereferences a pointer without checking whether the pointer is NULL, and when it is, you get Undefined Behavior.
It's not entirely clear what you intended, but you seem to misunderstand how variables work in C++.