Last week, we created a program that manages sets of strings, using classes and vectors. I was able to complete this 100%. This week, we have to replace the vector we used to store strings in our class with simple singly linked lists.
The function basically allows users to declare sets of strings that are empty, and sets with only one element. In the main file, there is a vector whose elements are a struct that contain setName and strSet (class).
HERE IS MY PROBLEM: It deals with the copy constructor of the class. When I remove/comment out the copy constructor, I can declare as many empty or single sets as I want, and output their values without a problem. But I know I will obviously need the copy constructor for when I implement the rest of the program. When I leave the copy constructor in, I can declare one set, either single or empty, and output its value. But if I declare a 2nd set, and i try to output either of the first two sets, i get a Segmentation Fault. Moreover, if i try to declare more then 2 sets, I get a Segmentation Fault. Any help would be appreciated!!
Here is my code for a very basic implementation of everything:
Here is the setcalc.cpp: (main file)
#include <iostream>
#include <cctype>
#include <cstring>
#include <string>
#include "help.h"
#include "strset2.h"
using namespace std;
// Declares of structure to hold all the sets defined
struct setsOfStr {
string nameOfSet;
strSet stringSet;
};
// Checks if the set name inputted is unique
bool isSetNameUnique( vector<setsOfStr> strSetArr, string setName) {
for(unsigned int i = 0; i < strSetArr.size(); i++) {
if( strSetArr[i].nameOfSet == setName ) {
return false;
}
}
return true;
}
int main(int argc, char *argv[]) {
char commandChoice;
// Declares a vector with our declared structure as the type
vector<setsOfStr> strSetVec;
string setName;
string singleEle;
// Sets a loop that will constantly ask for a command until 'q' is typed
while (1) {
// declaring a set to be empty
if(commandChoice == 'd') {
cin >> setName;
// Check that the set name inputted is unique
if (isSetNameUnique(strSetVec, setName) == true) {
strSet emptyStrSet;
setsOfStr set1;
set1.nameOfSet = setName;
set1.stringSet = emptyStrSet;
strSetVec.push_back(set1);
}
else {
cerr << "ERROR: Re-declaration of set '" << setName << "'\n";
}
}
// declaring a set to be a singleton
else if(commandChoice == 's') {
cin >> setName;
cin >> singleEle;
// Check that the set name inputted is unique
if (isSetNameUnique(strSetVec, setName) == true) {
strSet singleStrSet(singleEle);
setsOfStr set2;
set2.nameOfSet = setName;
set2.stringSet = singleStrSet;
strSetVec.push_back(set2);
}
else {
cerr << "ERROR: Re-declaration of set '" << setName << "'\n";
}
}
// using the output function
else if(commandChoice == 'o') {
cin >> setName;
if(isSetNameUnique(strSetVec, setName) == false) {
// loop through until the set name is matched and call output on its strSet
for(unsigned int k = 0; k < strSetVec.size(); k++) {
if( strSetVec[k].nameOfSet == setName ) {
(strSetVec[k].stringSet).output();
}
}
}
else {
cerr << "ERROR: No such set '" << setName << "'\n";
}
}
// quitting
else if(commandChoice == 'q') {
break;
}
else {
cerr << "ERROR: Ignoring bad command: '" << commandChoice << "'\n";
}
}
return 0;
}
Here is the strSet2.h:
#ifndef _STRSET_
#define _STRSET_
#include <iostream>
#include <vector>
#include <string>
struct node {
std::string s1;
node * next;
};
class strSet {
private:
node * first;
public:
strSet (); // Create empty set
strSet (std::string s); // Create singleton set
strSet (const strSet ©); // Copy constructor
// will implement destructor later
void output() const;
strSet& operator = (const strSet& rtSide); // Assignment
}; // End of strSet class
#endif // _STRSET_
And here is the strSet2.cpp (implementation of class)
#include <iostream>
#include <vector>
#include <string>
#include "strset2.h"
using namespace std;
strSet::strSet() {
first = NULL;
}
strSet::strSet(string s) {
node *temp;
temp = new node;
temp->s1 = s;
temp->next = NULL;
first = temp;
}
strSet::strSet(const strSet& copy) {
cout << "copy-cst\n";
node *n = copy.first;
node *prev = NULL;
while (n) {
node *newNode = new node;
newNode->s1 = n->s1;
newNode->next = NULL;
if (prev) {
prev->next = newNode;
}
else {
first = newNode;
}
prev = newNode;
n = n->next;
}
}
void strSet::output() const {
if(first == NULL) {
cout << "Empty set\n";
}
else {
node *temp;
temp = first;
while(1) {
cout << temp->s1 << endl;
if(temp->next == NULL) break;
temp = temp->next;
}
}
}
strSet& strSet::operator = (const strSet& rtSide) {
first = rtSide.first;
return *this;
}