i am working on a program that reads in a text file that the user inputs, creates a text file that the user inputs, names the text file that the user wants, and then sorts the text file sorting words above the user entered in threshold and displays the words and how many times it was found to the output file the user specify's. i have most of the code finished but im getting a compiler error heres the sample output, error and code
sample output
Enter name of input command file; press return.
history.in
Enter name of output file; press return.
history.out
Enter name of test run; press return.
sample
Enter the minimum size word to be considered.
5
Sample results (found in user specified output file):
sample
abacus 4
abstract 1
adding 1
addition 2
advances 1
after 3
where the word is the word found in the text file, and the number next to it is how many times it was found.
The compiler errors are:
C:\Users\kevin jack\Desktop\prog-4>g++ -o try main.cpp
main.cpp:(.text+0x329) undefined reference to `StrType::PrintToFile(bool, std::basic_ofstream<char, std::char_traits<char> >&)'
:main.cpp:(.text+0x608): undefined reference to `StrType::GetStringFile(bool, InType, std::basic_ifstream<char, std::char_traits<char> >&)'
main.cpp:(.text+0x639): undefined reference to `StrType::LenghtIs()'
main.cpp:(.text+0x6d8): undefined reference to `StrType::GetStringFile(bool, InType, std::basic_ifstream<char, std::char_traits<char> >&)'
collect2: ld returned 1 exit status
i have no idea what this means if anyone knows please inform me here is my code
main.cpp
//main.cpp
#include <fstream>
#include "StrType.h"
#include <cstddef>
#include <iostream>
#include <string>
using namespace std;
struct WordType
{
public:
StrType word;
int count;
};
struct TreeNode
{
WordType info;
TreeNode* left;
TreeNode* right;
};
class ListType
{
public:
ListType();
void InsertOrIncrement (StrType string);
void Print(std::ofstream&) const;
private:
TreeNode* root;
};
ListType::ListType()
{
root=NULL;
}
void Process(TreeNode*& tree, StrType s)
{
if(tree == NULL)
{
tree = new TreeNode;
tree->info.word = s;
tree->info.count = 1;
tree->left = NULL;
tree->right = NULL;
}
else if (tree->info.word == s)
tree->info.count++;
else if (s < tree->info.word)
Process(tree->left, s);
else
Process(tree->right, s);
}
void ListType::InsertOrIncrement(StrType s)
{
Process(root, s);
}
void Print (TreeNode* tree, std::ofstream& outFile)
{
if (tree!= NULL)
{
Print(tree->left, outFile);
tree->info.word.PrintToFile(true, outFile);
outFile <<" "<< tree->info.count;
Print(tree->right, outFile);
}
}
void ListType::Print(std::ofstream& outFile) const
{
::Print(root, outFile);
}
int main()
{
using namespace std;
ListType list;
string inFileName;
string outFileName;
string outputLabel;
ifstream inFile;
ofstream outFile;
StrType string;
int minimumLenght;
cout<<"enter in imput file name."<<endl;
cin>>inFileName;
inFile.open(inFileName.c_str());
cout<<"enter name of output file."<<endl;
cin>>outFileName;
outFile.open(outFileName.c_str());
cout<<"enter name of test run."<<endl;
cin>>outputLabel;
outFile<< outputLabel << endl;
cout<<"enter the min word size."<<endl;
cin>>minimumLenght;
string.GetStringFile(true, ALPHA_NUM, inFile);
while(inFile)
{
if(string.LenghtIs() >= minimumLenght)
list.InsertOrIncrement(string);
string.GetStringFile(true, ALPHA_NUM, inFile);
}
list.Print(outFile);
outFile.close();
inFile.close();
return 0;
}
StrType.h
//StrType.h
#include <fstream>
#include <iostream>
const int MAX_CHARS=100;
enum InType{ALPHA_NUM, ALPHA, NON_WHITE, NOT_NEW};
class StrType
{
public:
void MakeEmpty();
void GetString(bool skip, InType charsAllowed);
void GetStringFile(bool skip, InType charsAllowed,
std::ifstream& inFile);
void PrintToScreen(bool newLine);
void PrintToFile(bool newLine, std::ofstream& outFile);
int LenghtIs();
void CopyString(StrType& newString);
bool operator==(const StrType& other) const;
bool operator<(const StrType& other) const;
private:
char letters[MAX_CHARS + 1];
};
bool StrType::operator==(const StrType& other) const
{
return (strcmp(letters, other.letters) == 0);
}
bool StrType::operator<(const StrType& other) const
{
return (strcmp(letters, other.letters) < 0);
}
void StrType::MakeEmpty()
{
letters[0] ='\0';
}
what i was trying to overload the == and > operator. i am stating it in class StrType and defining it just below it but im not sure if im defining it correctly or even in the right spot! any help would be greatly appreciated
If you want to compile and check your code, you should define all member functions of all classes at least as (nearly) empty functions.
void StrType::GetString(bool skip, InType charsAllowed)
{
// empty function, you will write your code heree later
}
// ...
Don't forget about return-values for non-void functions
notMine.cpp
//StrType.h
#include <fstream>
#include <iostream>
const int MAX_CHARS=100;
enum InType{ALPHA_NUM, ALPHA, NON_WHITE, NOT_NEW};
class StrType
{
public:
void MakeEmpty();
void GetString(bool skip, InType charsAllowed)
{
}
void GetStringFile(bool skip, InType charsAllowed, std::ifstream& inFile)
{
}
void PrintToScreen(bool newLine)
{
}
void PrintToFile(bool newLine, std::ofstream& outFile)
{
}
int LenghtIs()
{
return 0;
}
void CopyString(StrType& newString)
{
}
bool operator==(const StrType& other) const
{
return (strcmp(letters, other.letters) == 0);
}
bool operator<(const StrType& other) const
{
return (strcmp(letters, other.letters) < 0);
}
private:
char letters[MAX_CHARS + 1];
};
void StrType::MakeEmpty()
{
letters[0] ='\0';
}
myOwnSomething.h
#include <stdio.h>
#include <fstream>
#include <cstddef>
#include <iostream>
#include <string>
#include "myOwnSomething.h"
using namespace std;
struct WordType
{
public:
StrType word;
int count;
};
struct TreeNode
{
WordType info;
TreeNode* left;
TreeNode* right;
};
class ListType
{
public:
ListType();
void InsertOrIncrement (StrType string);
void Print(std::ofstream&) const;
private:
TreeNode* root;
};
ListType::ListType()
{
root=NULL;
}
void Process(TreeNode*& tree, StrType s)
{
if(tree == NULL)
{
tree = new TreeNode;
tree->info.word = s;
tree->info.count = 1;
tree->left = NULL;
tree->right = NULL;
}
else if (tree->info.word == s)
tree->info.count++;
else if (s < tree->info.word)
Process(tree->left, s);
else
Process(tree->right, s);
}
void ListType::InsertOrIncrement(StrType s)
{
Process(root, s);
}
void Print (TreeNode* tree, std::ofstream& outFile)
{
if (tree!= NULL)
{
Print(tree->left, outFile);
tree->info.word.PrintToFile(true, outFile);
outFile <<" "<< tree->info.count;
Print(tree->right, outFile);
}
}
void ListType::Print(std::ofstream& outFile) const
{
::Print(root, outFile);
}
int main()
{
using namespace std;
ListType list;
string inFileName;
string outFileName;
string outputLabel;
ifstream inFile;
ofstream outFile;
StrType string;
int minimumLenght;
cout<<"enter in imput file name."<<endl;
cin>>inFileName;
inFile.open(inFileName.c_str());
cout<<"enter name of output file."<<endl;
cin>>outFileName;
outFile.open(outFileName.c_str());
cout<<"enter name of test run."<<endl;
cin>>outputLabel;
outFile<< outputLabel << endl;
cout<<"enter the min word size."<<endl;
cin>>minimumLenght;
string.GetStringFile(true, ALPHA_NUM, inFile);
while(inFile)
{
if(string.LenghtIs() >= minimumLenght)
list.InsertOrIncrement(string);
string.GetStringFile(true, ALPHA_NUM, inFile);
}
list.Print(outFile);
outFile.close();
inFile.close();
return 0;
}
Related
So I implemented Stack basic operations in c++.I wrote the functions but I don't know how to implement the main the function such that to see the values from the stack.
header file
#ifndef HEADER_H_
#define HEADER_H_
#define DIM 15
typedef int Atom;
struct Element {
Atom data;
Element *link;
};
typedef Element* LinkedStack;
void initS(LinkedStack &S);
void push(LinkedStack &S, Atom a);
bool isEmpty2(LinkedStack &S);
void pop2(LinkedStack &S);
Atom top2(Stack &S);
#endif
The functions file
void initS(LinkedStack &S)
{
S = nullptr;
}
void push(LinkedStack &S, Atom a)
{
Element*nou = new Element;
nou->data = a;
nou->link = S;
S = nou;
}
bool isEmpty2(LinkedStack &S)
{
if (S == 0)
return true;
else return false;
}
void pop2(LinkedStack &S)
{
LinkedStack aux = S;
S = S->link;
delete(aux);
}
Atom top2(LinkedStack &S)
{
if (isEmpty2(S))
return Atom();
return S->data;
}
How I implemented the main function.I don't know how to see values, for example if I write cout<
#include <iostream>
#include "header.h"
using namespace std;
int main()
{
LinkedStack S;
initS(S);
push(S, 2);
push(S, 4);
push(S, 6);
push(S, 7);
push(S, 10);
return 0;
}
After I compile the program I don't see nothing in console.How to see the values from stack?
I have given it a few tries based on what I've read on numerous forums and books I have here. More details about this assignment here with more code from it: Click- another question from StackOverflow
What exactly I need to do is create a file with CHotel objects and insert them in this vector m_hoteli.
As to why it isn't working, it is either not reading the string from the file and it's not filling the vector at all.
This is my file:
"Marina" 5 500
"Tulip" 4 400
"BlackSea" 3 300
"SwissBell" 5 600
class CComplex:CHotel
{
protected:
string m_complex;
vector<CHotel> m_hoteli;
public:
CComplex(){};
CComplex(string filename, string nComplex)
{
fstream file("filename.txt", ios::in);
CHotel temp(" ",0,0);
while (file >> temp)
{
m_hoteli.push_back(temp);
}
/* Second try:
m_complex = nComplex;
fstream in;
in.open(filename, ios::in);
string s;
while (getline(in, s))
{
CHotel h1(s);
m_hoteli.push_back(h1);
}
Third try:
m_complex = nComplex;
ifstream iStream(filename);
if (iStream.good())
{
copy(istream_iterator<CHotel>(iStream), istream_iterator<CHotel>(), back_inserter(m_hoteli));
}
}
*/
}
That's the CHotel code:
class CHotel : public CTurist
{
protected:
string hName;
int stars;
int beds;
map<CTurist, unsigned> Turisti;
public:
unsigned Sum = 0;
int br = 0;
CHotel(){};
CHotel(string hName2, int zvezdi, int legla)
{
hName = hName;
stars = zvezdi;
beds = legla;
}
friend istream& operator>>(std::istream& is, CHotel& e)
{
is >> e.hName >> e.stars >> e.beds;;
return is;
}
I just do this in the main: CComplex c1("filename.txt", "Complex1");
You are not using the filename parameter in the CComplex constructor, other than that your code should work.
fstream file(filename, ios::in);
Do you know how to step debug? Here is some info on debugging
Here is your full code, the only change is the filename parameter and the file should now be placed in c:\temp.
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <fstream>
using namespace std;
class CTurist
{
protected:
string tName;
int age;
public:
CTurist() {};
CTurist(string name, int age2)
{
tName = name;
age = age2;
}
bool operator<(const CTurist& e) const
{
return age < e.age;
}
friend ostream& operator<<(ostream& os, const CTurist&& e);
friend ifstream& operator>>(ifstream& is, CTurist&& e);
};
class CHotel : public CTurist
{
protected:
string hName;
int stars;
int beds;
map<CTurist, unsigned> Turisti;
public:
unsigned Sum = 0;
int br = 0;
CHotel() {};
CHotel(string hName2, int zvezdi, int legla)
{
hName = hName;
stars = zvezdi;
beds = legla;
}
friend istream& operator>>(std::istream& is, CHotel& e)
{
is >> e.hName >> e.stars >> e.beds;;
return is;
}
};
class CComplex :CHotel
{
protected:
string m_complex;
vector<CHotel> m_hoteli;
public:
CComplex() {};
CComplex(string filename, string nComplex)
{
fstream file(filename, ios::in);
CHotel temp(" ", 0, 0);
while (file >> temp)
{
m_hoteli.push_back(temp);
}
}
};
int main()
{
CComplex c1("C:\\temp\\file.txt", "Complex1");
system("pause");
return 0;
}
Try putting a breakpoint in main and step through your program with f11 and f10
So I implemented an array-based list to store a bunch of (x,y) pairs. Here is what I have
list.h
#ifndef LIST
#define LIST
class list{
float * values;
int size,last;
public:
float getValue(int);
int getSize();
void setValue(int,float);
bool insert(const float);
void resize(int);
list();
~list();
};
#endif
list.cpp
#include <iostream>
#include "list.h"
using namespace std;
int list::getSize()
{
return size;
}
float list::getValue(int a)
{
if (a<size && a >=0)
return values[a];
}
void list::setValue(int a ,float b)
{
if (a<size && a >=0)
values[a]=b;
}
bool list::insert(const float a)
{
if (a==NULL || a==EOF){
return false;
}
if(last+1<size && last+1>=0)
{
values[last+1]=a;
last++;
return true;
}
else if (last+1>=size)
{
resize(size+1+((last+1)-size));
values[last+1]=a;
last++;
return true;
}
return false;
}
void list::resize(int dim){
float *temp=new float[size];
for (int i=0;i<size;i++)
temp[i]=values[i];
delete [] values;
values=new float [dim];
for (int b=0;b<dim;b++)
{
if (b<size)
values[b]=temp[b];
else
values[b]=NULL;
}
size=dim;
delete []temp;
}
list::list(){
//The expected input is always >2000.
values=new float[2000];
size=2000;
last=-1;
}
list::~list()
{
delete[]values;
}
main.cpp
`
#include <fstream>
#include <iostream>
#include "list.h"
using namespace std;
int main()
{
ifstream file("test.txt");
list X,Y;
float x,y;
if (file)
{
while(file>>x)
{
X.insert(x);
file>>y;
Y.insert(y);
}
}
ofstream outfile("out.txt");
for(int i=0;i<X.getSize();i++)
outfile<<i+1<<" "<<X.getValue(i)<<" "<<Y.getValue(i)<<endl;
system("notepad.exe out.txt");
//system("pause");
return 0;
}
The input stream seems to skip any value equal to -1. My question is: Is there a particular reason why -1 is being skipped?
Also: I know I can use the STL or more efficient lists, this is just for practice.
EOF is -1 for most implementations, so if (a==NULL || a==EOF){ filters the -1 if this is the case in your implementation.
in my school assignment i need a small help
this is my header file:
#include <iostream>
#include <cstring>
using namespace std;
#include "ISBNPrefix.h"
class ISBN
{
char str[11];
char area[6];
char publisher[8];
char title[7];
bool registered;
public:
ISBN();
ISBN(const char*,ISBNPrefix &);
void toStr(char*)const;
void toStrWithStyle(char*)const;
bool empty()const;
bool isRegistered() const;
bool read(istream& is, const ISBNPrefix& list);
void display(ostream&) const;
};
int isValid(const char* str);
and this is the implementation of my file:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include <iomanip>
using namespace std;
#include "ISBN.h"
ISBN::ISBN()
{
str[0]='\0';
area[0]='\0';
publisher[0]='\0';
title[0]='\0';
registered=false;
}
ISBN::ISBN(const char* s,ISBNPrefix& p)
{
if(isValid(s)==1)
{
strcpy_s(str,s);
}
else
{
*this=ISBN();
}
}
bool ISBN::empty()const
{
bool chk=false;
if(str[0]=='\0')
chk=true;
return chk;
}
void ISBN::toStrWithStyle(char* s) const
{
if(registered)
{
sprintf(s,"%s-%s-%s-%c",area,publisher,title,str[9]);
}
else
{
toStr(s);
}
}
void ISBN::toStr(char* s) const
{
if (str[0]!='\0')
strcpy(s,str);
else
strcpy(s,"no data");
}
void ISBN::display(ostream & os) const
{
char str[14];
toStrWithStyle(str);
cout<< setw (13) <<str;
}
int isValid(const char* str)
{
int rc=0;
if(str!=0)
{
int sum,i=0;
sum=0;
for(i=0;i<10;i++)
sum+=(str[i]-'0')*(10-i);
if(sum%11==0)
{
rc= 1;
}
}
else
rc=0;
return rc;
}
bool ISBN::read(istream& is, const ISBNPrefix& list)
{
char str[11];
bool quit=false;
bool ok=false;
char lists;
do{
cout<<"ISBN (0 to quit) : ";
is.getline(str,11); //or is.get(str,11)
if(strcmp(str,"0")==0)
quit=true;
else if (isValid(str)==1)
{
*this=ISBN(str,list);
ok=true;
cout<<"isbn is valid"<<endl;
}
else
{
*this=ISBN();
cout<<"invalid ISBN"<<endl;
}
} while(!quit&&!ok);
return !quit;
}
in the ISBN::read where I say
*this=ISBN(str,list);
i want to overload another member but i can't.
can anyone tell me how can i do that?
First I would suggest use std::string in favour of char[]. It will save a lot of trouble. For reading ISBN I would write something like this:
bool ISBN::read(istream& is)
{
ISBN result;
// reading into result
std::swap(*this,result);
return !quit;
}
Or even better (as a non member function):
std::istream& operator>>(istream& is, ISBN& obj)
{
ISBN result;
// reading into result
is(!quit)
is.clear(std::ios_base::failbit);
std::swap(obj,result);
return is;
}
In any way you should RAII classes for your resources. In your special case std::string instead of char[].
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
I'm working on implementing a chain data structure, using a specific set of pre-made templates. Upon compilation, I'm receiving the error in the title.
arrayList.h:
#ifndef arrayList_h
#define arrayList_h
#include <iostream>
#include "linearList.h"
using namespace std;
template<class T>
class arrayList : public linearList<T>{
public:
//constructor, copy constructor, destructor
arrayList(int initialCapacity = 10);
arrayList(const arrayList<T>&);
~arrayList() {delete [] element;};
//ADT methods
bool empty() const {return listSize == 0;};
int size() const {return listSize;};
T& get(int theIndex) const;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void insert(int theIndex, const T& theElement);
void output(ostream& out) const;
//additional method
int capacity() const {return arrayLength;};
protected:
void checkIndex(int theIndex) const;
//throw illegalIndex if theIndex is invalid
T* element; //1D array to hold list elements
int arrayLength; //capacity of 1D array
int listSize; //number of elements in list
};
#endif
chain.h:
#ifndef chain_h
#define chain_h
#include <iostream>
#include "linearList.h"
#include "chainNode.h"
using namespace std;
template<class T>
class chain : public linearList<T>{
public:
// constructor and destructor
chain(int initialCapacity = 10);
//chain(const chain<T>&);
~chain();
// ADT methods
bool empty() const {return listSize == 0;}
int size() const {return listSize;}
T& get(int theIndex) const;
int indexOf(const T& theElement) const;
void erase(int theIndex);
void insert(int theIndex, const T& theElement);
void output(ostream& out) const;
protected:
void checkIndex(int theIndex) const;
chain<T>* firstNode;
int listSize;
};
#endif
chainNode.h:
#ifndef chainNode_h
#define chainNode_h
#include <iostream>
template <class T>
struct chainNode
{
// data members
T element;
chainNode<T> *next;
// methods
chainNode() {}
chainNode(const T& element)
{this->element = element;}
chainNode(const T& element, chainNode<T>* next)
{this->element = element;
this->next = next;}
};
#endif
chain.cpp:
#include "chain.h"
#include "person.h"
using namespace std;
template<class T>
chain<T>::chain(int initialCapacity){
// Constructor.
/*if (initialCapacity < 1){
ostringstream s;
s << "Initial capacity = "
<< initialCapacity << " Must be > 0";
throw illegalParameterValue(s.str());
}*/
firstNode = NULL;
listSize = 0;
}
template<class T>
chain<T>::~chain(){
// Chain destructor. Delete all nodes
// in chain.
while (firstNode != NULL){
// delete firstNode
chainNode<T>* nextNode = firstNode->next;
delete firstNode;
firstNode = nextNode;
}
}
template<class T>
T& chain<T>::get(int theIndex) const{
// Return element whose index is theIndex.
checkIndex(theIndex);
// move to desired node
chainNode<T>* currentNode = firstNode;
for (int i = 0; i < theIndex; i++)
currentNode = currentNode->next;
return currentNode->element;
}
template<class T>
int chain<T>::indexOf(const T& theElement) const{
// search the chain for theElement
chainNode<T>* currentNode = firstNode;
int index = 0; // index of currentNode
while (currentNode != NULL && currentNode->element != theElement){
// move to next node
currentNode = currentNode->next;
index++;
}
// make sure we found matching element
if (currentNode == NULL)
return -1;
else
return index;
}
template<class T>
void chain<T>::erase(int theIndex){
checkIndex(theIndex);
chainNode<T>* deleteNode;
if (theIndex == 0){
// remove first node from chain
deleteNode = firstNode;
firstNode = firstNode->next;
}
else{
// use p to get to beforeNode
chainNode<T>* p = firstNode;
for (int i = 0; i < theIndex - 1; i++)
p = p->next;
deleteNode = p->next;
p->next = p->next->next;
}
listSize--;
delete deleteNode;
}
template<class T>
void chain<T>::insert(int theIndex, const T& theElement){
if (theIndex < 0 || theIndex > listSize){
// THROW ILLEGAL EXCEPTION
}
if (theIndex == 0) // insert at front
firstNode = new chainNode<T>(theElement, firstNode);
else{
// find predecessor of new element
chainNode<T>* p = firstNode;
for (int i = 0; i < theIndex - 1; i++)
p = p->next;
// insert after p
p->next = new chainNode<T>(theElement, p->next);
}
listSize++;
}
Person.h:
#ifndef Person_h
#define Person_h
#include <string>
#include <sstream>
using namespace std;
class Person{
public:
//Variables
string birthdate;
string first_name;
string last_name;
string hometownID;
string hometownName;
string userID;
string name;
//Constructors
Person();
Person(string birthdate, string first_name, string last_name, string hometownID, string hometownName, string userID);
//Methods
string getBirthdate();
void setBirthdate(string birthdate);
string getFirst_name();
void setFirst_name(string first_name);
string getLast_name();
void setLast_name(string last_name);
string getName();
void setName(string name);
string getHometownID();
void setHometownID(string hometownID);
string getHometownName();
void setHometownName(string hometownName);
string getUserID();
void setUserID(string userID);
int compare(Person& p, int criteria);
//Comparisons
friend bool operator== (Person p1, Person p2);
friend bool operator!= (Person &p1, Person &p2);
friend bool operator> (Person &p1, Person &p2);
friend bool operator>= (Person &p1, Person &p2);
friend bool operator< (Person &p1, Person &p2);
friend bool operator<= (Person &p1, Person &p2);
friend ostream& operator<<(ostream& os, const Person& p);
};
#endif
Person.cpp: I've cut this down quite a bit. I currently don't have anything having to do with Node within this.
#include "Person.h"
#include <sstream>
#include <string>
using namespace std;
Person::Person(){
birthdate = "";
name = "";
hometownID = "";
hometownName = "";
userID = "";
}
Person::Person(string birthdate, string first_name, string last_name, string hometownID, string hometownName, string userID){
this->birthdate = birthdate;
this->first_name = first_name;
this->last_name = last_name;
this->hometownID = hometownID;
this->hometownName = hometownName;
this->userID = userID;
name = last_name+ ", " +first_name;
}
//mostly get/set methods after here, nothing having to do with node.
main.cpp:
#include "arrayList.cpp"
#include "block_allocator.h"
#include "chain.cpp"
#include "chainNode.h"
#include "json.h"
#include "linearList.h"
#include "Person.h"
#include <string>
#include <fstream>
#include <streambuf>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <time.h>
using namespace std;
//ArrayList helper methods
arrayList<Person> arrayListStructure(string fileName);
int arrayListSort(int criteria, arrayList<Person>* list);
void arrayListReverseSort(int criteria, arrayList<Person>* list);
int arrayListFlip(arrayList<Person>* list);
//Chain helper methods
chain<Person> chainStructure(string fileName);
//Hashtable helper methods
int main(int argc, const char * argv[]){
//get fileName
cout << "Please enter a filename:" << endl;
string fileName;
cin >> fileName;
//get data structure type
cout << "Please choose a data structure:" << endl;
cout << " 1. Arraylist" << endl;
cout << " 2. Chain" << endl;
cout << " 3. Hashtable" << endl;
int dataStructure;
cin >> dataStructure;
cout << "Please choose a criteria:" << endl;
cout << " 1. Name" << endl;
cout << " 2. Birthday" << endl;
cout << " 3. Location" << endl;
int criteria;
cin >> criteria;
arrayList<Person> friends;
chain<Person> friendChain;
//parse file into data structure
switch(dataStructure){
case 1: //Arraylist
//edited out, irrelevant
/*case 2:
//Chain
//code goes here
/*switch(criteria){
case 1: //Name
case 2: //Birthday
case 3: //Location
}
break;*/
/*case 3:
//Hashtable
//code goes here
break;
*/
}
}
//Helper methods for chain
chain<Person> chainStructure(string fileName){
//create initial (empty) chain
chain<Person> friends;
//open input file
ifstream fileInput(fileName);
//turn input stream into string
string inputStr((istreambuf_iterator<char>(fileInput)), istreambuf_iterator<char>());
//parse file content into json object
char *errorPos = 0;
char *errorDesc = 0;
int errorLine = 0;
block_allocator allocator(1 << 10);
json_value *root = json_parse(const_cast<char*>(inputStr.c_str()), &errorPos, &errorDesc, &errorLine, &allocator);
//Take value of first element
json_value *list = root->first_child;
//Outer loop addresses each friend's JSON object
for(json_value *it = list->first_child; it; it = it->next_sibling){
string first_name, last_name, birthdate, hometownID, hometownName, userID;
//Inner loop looks at each key/value pair within each friend object
for(json_value *friendKeys = it->first_child; friendKeys; friendKeys = friendKeys->next_sibling){
//grab first name
if(!string(friendKeys->name).compare("first_name")){
first_name = friendKeys->string_value;
}
//grab last name
else if(!string(friendKeys->name).compare("last_name")){
last_name = friendKeys->string_value;
}
//grab birthday and trim to 5 characters
else if(!string(friendKeys->name).compare("birthday")){
birthdate = friendKeys->string_value;
birthdate = birthdate.substr(0, 5);
}
//grab hometown info
else if(!string(friendKeys->name).compare("hometown")){
for(json_value *hometownKeys = friendKeys->first_child; hometownKeys; hometownKeys = hometownKeys->next_sibling){
if(!string(hometownKeys->name).compare("id")){
hometownID = hometownKeys->string_value;
}
if(!string(hometownKeys->name).compare("name")){
hometownName = hometownKeys->string_value;
}
}
}
//grab userID
else if(!string(friendKeys->name).compare("id")){
userID = friendKeys->string_value;
}
}
if(birthdate != "" && first_name != "" && last_name != "" && hometownID != "" && hometownName != "" && userID != ""){
//Create new Person in chain
Person person(birthdate, first_name, last_name, hometownID, hometownName, userID);
friends.insert(friends.size(), person);
}
}
//return friends;
return friends;
}
//Helper methods for hashtable
So I know this is a huge wall of text, but I'm really not sure where this disconnect is, and I didn't want to provide too little information. Any help or advice would be greatly appreciated, as I'm very new to C++, and even more inexperienced with using the template system.
EDIT: linearList.h:
#ifndef linearList_h
#define linearList_h
#include <iostream>
using namespace std;
template<class T>
class linearList
{
public:
virtual ~linearList() {};
virtual bool empty() const = 0;
// return true iff list is empty
virtual int size() const = 0;
// return number of elements in list
virtual T& get(int theIndex) const = 0;
// return element whose index is theIndex
virtual int indexOf(const T& theElement) const = 0;
// return index of first occurence of theElement
virtual void erase(int theIndex) = 0;
// remove the element whose index is theIndex
virtual void insert(int theIndex, const T& theElement) = 0;
// insert theElement so that its index is theIndex
virtual void output(ostream& out) const = 0;
// insert list into stream out
};
#endif
In chain.h, the chain<T> template has this for a member:
chain<T>* firstNode;
I'm pretty sure that should be:
chainNode<T>* firstNode;
There may be other errors (or maybe not), but that appears the likely one causing your current issue that is the subject of this question.
Side Bar: This thing needs a serious refactor to use the containers and algorithms from the standard library (std::vector<T>, std::list<T>, etc...) Just consider it.