I am having a terrible time separating this code into a header file and source file. I am running this on cygwin and it keeps giving me error messages I do not know how to solve... any help would be greatly appreciated

#include <fstream>
#include <vector>
#include <string>
#include <iostream>
#include <ctime>

using namespace std;

int primes [21] = {3, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169};

class hashTable {

 public:
 
 hashTable(int size = 0)
 {
	data.resize(getPrime(size));
	capacity = data.size();
	hashItem *x = new hashItem();
	for(int i=0; i<capacity; i++)
		data[i] = *x;
	
	filled = 0;
 }

 
 bool contains(const string &key)
 {
	if(findPos(strToLow(key)) != -1)
		return true;
	else return false;
}
 
 void *getPointer(const string &key, bool *b = NULL)
 {
	if(!contains(key))
		return NULL;
		
	hashItem *x = new hashItem(key, b);
	
	if(b!=NULL)
	{
		*b = true;
		(*x).setPt(b);
	}
	else
	{
		*b= false;
		(*x).setPt(b);
	} 
 }
 
 int insert(const string &key, void *pv = NULL)
 {
	if(contains(key))
		return 1;
	
	string k = strToLow(key);
	int val = hash(k);
	hashItem *x = new hashItem(k, pv);
	while(data[val].occupied())
	{
		val++;
		
		if(val >= capacity)
			val-=capacity;
	}
	data[val] = *x;
	
	data[val].setOcc(true);
	filled++;
	
	if(filled >= capacity/2)
	{
		if(rehash())
			return 0;
		else
			return 2; 
	} 
	else
		return 0;
}
 
 bool remove(const string &key)
 {
	string k = strToLow(key);
	if(!contains(k))
		return false;
	else
	{
		int x = findPos(k);
		data[x].setDel(true); 
		data[x].setOcc(false);
		filled--;
	}
}
	
 void print()
 {
 	cout<<"the capacity is\t"<<capacity<<endl;
	for(int i =0; i<capacity; i++)
		if(data[i].occupied())
			cout<<i<<"\t"<<data[i].getKey()<<endl;
	
	cout<<"there are "<<filled<<" entries"<<endl;
}

string strToLow(string str)
{
	for(int i =0; i<str.size(); i++)
		if((int)str[i] >=65 && (int)str[i]<=90)
			str[i]+=32;
			
	return str;
}
 
 private:
  
  class hashItem {
    public:
	string key;
    bool isOccupied;
	bool isDeleted;
	void *pv;
	
	hashItem(const string &k = "", void *pt = NULL)
	{
		key = k;
		isOccupied = false;
		isDeleted = false;
		pv = pt;
	}
	
	string getKey(){
		return key;
	}
	
	bool occupied(){
		return isOccupied;
	}
	
	bool deleted(){
		return isDeleted;
	}
	
	void* getPt(){
		return pv;
	}
	
	void setKey(string str){
		key =str;
	}
	
	void setDel(bool x){
		isDeleted = x;
	}
	
	void setOcc(bool x){
		isOccupied = x;
	}
	
	void setPt(void *r){
		pv =r;
	}
		
  };

	vector<hashItem> data; // The actual entries are here.
	int capacity; // The current capacity of the hash table.
	int filled;  // Number of occupied items in the table.


	int hash(const string &key)
	{
		int val = 0;
		if(key.size()>0)
		{
			for(int i =0; i<key.size(); i++)
				val =37 * val + key[i];
			
			val %= capacity;
			
			if(val < 0)
				val+=capacity;
			
			return val;
		}
		else return 0;
	}
	
	int findPos(const string &key)
	{
		int val = hash(key);
	
		while(data[val].occupied() && data[val].getKey() != key)
		{
			val++;
			
			if(val >= capacity)
				val-=capacity;
		}
		
		if(data[val].getKey() == key && !(data[val].deleted()))
			return val;
		else
			return -1;		
	}
	
	bool rehash()
	{
		int oldCap = capacity;
		vector<hashItem> oldArr = data;
		
		data.resize(getPrime(2*oldCap));
		capacity = data.size();
		int r;
		
		for(int i =0; i<capacity; i++)
		{
			data.at(i).setOcc(false);
			data.at(i).setKey("");
		}
			
			
		filled = 0;
		for(int j =0;j<oldCap; j++)
			if(oldArr[j].occupied())
			{
				r = insert(oldArr[j].getKey());
				if(r != 0)
					return false;
			}
					
		return true;
	}

	static unsigned int getPrime(int size)
	{
		int pow = 2;
		int ind = 0;

		while(size > pow)
		{
			pow*=2;
			ind++;
		}
		if(ind>21)
			return NULL;
		
		return primes[ind];
	}
};

string strToLower(string str)
{
	for(int i =0; i<str.size(); i++)
		if((int)str[i] >=65 && (int)str[i]<=90)
			str[i]+=32;
			
	return str;
}

vector<string> explode(string del, string str)
{
	vector<string> arr;
	int len = str.length();
	string toput;
	size_t found;
	found = str.find_first_not_of(del);
	
	while(found!=string::npos)
	{
		str[found] = ' ';
		found = str.find_first_not_of(del,found+1);
	}
	
	int k=0;
	size_t fo;
	for(int i= 0; i<len; i++)
	{
		if(str[i] == ' ')
		{
			toput = str.substr(k,i-k);
			fo = toput.find_first_of("0123456789");
			if(fo == string::npos)
			{
				arr.push_back(toput);
				k=i+1;
			}
			
		}
	}
	
	if(arr.size() == 0)
		arr.push_back(str);
	else
		arr.push_back(str.substr(k,len-k));
	
	return arr;
}

vector<string> clean(vector<string> vect)
{
	for(int i =0; i<vect.size(); i++)
		if(vect[i].compare(" \r") == 0)
		{
			vect.erase(vect.begin() + i);
			i--;
		}
	
	return vect;
}

int main()
{
	hashTable *table = new hashTable();
	int k;
	int cap=0;

	string line;
	string word;
	string temp;
	char file[50];
	char file2[50];
	char ofile[50]; 
	
	cout << "Enter name of dictionary: ";
	cin >>  file;
	

	fstream myfile;
	myfile.open(file);
	
	size_t found;
	string str,word1;
	int i=0;
	
	//read files into hashtable
	clock_t t1 = clock();
	if (myfile.is_open())
	{
		while (! myfile.eof() )
		{
			getline (myfile,line);
			if(line.size()<21)
			{
				str = strToLower(line);
				found=str.find_first_not_of("abcdefghijklmnopqrstuvwxyz0123456789'-\n");//\r\n");
				if (!(found!=string::npos))
					k = (*table).insert(str);
					
				if(k!=0)
					continue;
			}
		}
		myfile.close();
	}
	else
		cout<<"unable to open file"<<endl;
	clock_t t2 = clock();
	double timeDiff1 = ((double) (t2 - t1)) / CLOCKS_PER_SEC;
	
	cout<<"Total time (in seconds) to load dictionary: "<<timeDiff1<<endl;
	
	cout << "Enter name of input file: ";
	cin >>  file2;
	cout<<"Enter name of output file: ";
	cin>> ofile;
	ofstream file_op(ofile);
	
	int lijn =1;
	fstream myfile2;
	myfile2.open(file2);
	vector<string> arr;
	clock_t t3 = clock();
	if (myfile2.is_open())
	{
		while (! myfile2.eof())
		{
			getline(myfile2,line);
			arr = explode("abcdefghijklmnopqrstuvwxyz0123456789'-\n",strToLower(line)); 
			
			for(int l = 0; l<arr.size(); l++)
			{
				if(arr[l].size() <21)
				{
					if(!(*table).contains(arr[l]))
						file_op<<"Unknown word at line "<<lijn<<": "<<arr[l]<<endl;
				}
				else
					file_op<<"Long word at line "<<lijn<<", starts: "<<arr[l].substr(0,20)<<endl;
			}
			lijn++;
		}
		myfile2.close();
	}
	else
		cout<<"unable to open file"<<endl;
	clock_t t4 = clock();
	double timeDiff2 = ((double) (t4 - t3)) / CLOCKS_PER_SEC;
	
	cout<<"Total time (in seconds) to check document: "<<timeDiff2<<endl;
	
}

The code works, that isn't the issue. I run into trouble with the fact that theres a private nested class there. I am aware that I cannot have any initial values in the function heads in the source file and that I need scope specifiers (hashTable:: ) in front of the functions and (hashTable::hashItem:: ) in front of the nested class's functions, but aside from that I really don't know... perhaps a good tutorial would be helpful...

Edited 6 Years Ago by dmr9215: n/a

here is what I think should be the header file, hash.h

#ifndef HASH_H
#define HASH_H

#include <vector>
#include <string>

class hashTable {

 public:

  hashTable(int size = 0);

  int insert(const std::string &key, void *pv = NULL);

  bool contains(const std::string &key);

  void *getPointer(const std::string &key, bool *b = NULL);

  bool remove(const std::string &key);
  
  std::string strToLow(std::string str);
	
 private:

  class hashItem {
  public:
	hashItem(const string &k = "", void *pt = NULL);
    std::string key;
    bool isOccupied;
    bool isDeleted;
    void *pv;

	std::string getKey();
	bool occupied();
	bool deleted();
	void* getPt();
	void setKey(std::string str);
	void setDel(bool x);
	void setOcc(bool x);
	void setPt(void *r);
  };

  int capacity; // The current capacity of the hash table.
  int filled;  // Number of occupied items in the table.

  std::vector<hashItem> data; // The actual entries are here.

  int hash(const std::string &key);

  int findPos(const std::string &key);

  bool rehash();

 
  static unsigned int getPrime(int size);
};

#endif //_HASH_H

here is the code that doesn't work with this header:

#include "hash.h"
#include <fstream>
#include <iostream>
#include <ctime>


using namespace std;

int primes [21] = {3, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169};

 hashTable::hashTable(int size)
 {
	data.resize(getPrime(size));
	capacity = data.size();
	hashItem *x = new hashItem();
	for(int i=0; i<capacity; i++)
		data[i] = *x;
	
	filled = 0;
 }

 
 bool hashTable::contains(const string &key)
 {
	if(findPos(strToLow(key)) != -1)
		return true;
	else return false;
}
 
 void* hashTable::getPointer(const string &key, bool *b)
 {
	if(!contains(key))
		return NULL;
		
	hashItem *x = new hashItem(key, b);
	
	if(b!=NULL)
	{
		*b = true;
		(*x).setPt(b);
	}
	else
	{
		*b= false;
		(*x).setPt(b);
	} 
 }
 
 int hashTable::insert(const string &key, void *pv)
 {
	if(contains(key))
		return 
	string k = strToLow(key);
	int val = hash(k);
	hashItem *x = new hashItem(k, pv);
	while(data[val].occupied())
	{
		val++;
		
		if(val >= capacity)
			val-=capacity;
	}
	data[val] = *x;
	
	data[val].setOcc(true);
	filled++;
	
	if(filled >= capacity/2)
	{
		if(rehash())
			return 0;
		else
			return 2; 
	} 
	else
		return 0;
	
	
 }
 
 bool hashTable::remove(const string &key)
 {
	string k = strToLow(key);
	if(!contains(k))
		return false;
	else
	{
		int x = findPos(k);
		data[x].setDel(true); 
		data[x].setOcc(false);
		filled--;
	}
}
	
/* void print()
 {
	string txt ("");
	for(int i =0; i<capacity; i++)
		if(data[i].occupied())
			txt+= i+"\t"+data[i].getKey()+"\n";
	
	
	return txt;
	
	cout<<"the capacity is\t"<<capacity<<endl;
	for(int i =0; i<capacity; i++)
		if(data[i].occupied())
			cout<<i<<"\t"<<data[i].getKey()<<endl;
	
	cout<<"there are "<<filled<<" entries"<<endl;
}*/

string hashTable::strToLow(string str)
{
	for(int i =0; i<str.size(); i++)
		if((int)str[i] >=65 && (int)str[i]<=90)
			str[i]+=32;
			
	return str;
}
 
 hashTable::hashItem::hashItem(const string &k, void *pt)
{
	key = k;
	isOccupied = false;
	isDeleted = false;
	pv = pt;
}

string hashTable::hashItem::getKey(){
	return key;
}

bool hashTable::hashItem::occupied(){
	return isOccupied;
}

bool hashTable::hashItem::deleted(){
	return isDeleted;
}

void* hashTable::hashItem::getPt(){
	return pv;
}

void hashTable::hashItem::setKey(string str){
	key =str;
}

void hashTable::hashItem::setDel(bool x){
	isDeleted = x;
}

void hashTable::hashItem::setOcc(bool x){
	isOccupied = x;
}

void hashTable::hashItem::setPt(void *r){
	pv =r;
}

int hashTable::hash(const string &key)
{
	int val = 0;
	if(key.size()>0)
	{
		for(int i =0; i<key.size(); i++)
				val =37 * val + key[i];
		
		val %= capacity;
		
		if(val < 0)
			val+=capacity;
		
		return val;
	}
	else return 0;
}
	
int hashTable::findPos(const string &key)
{
	int val = hash(key);
	
	while(data[val].occupied() && data[val].getKey() != key)
	{
		val++;
		
		if(val >= capacity)
			val-=capacity;
	}
	
	if(data[val].getKey() == key && !(data[val].deleted()))
		return val;
	else
		return -1;		
}

bool hashTable::rehash()
{
	int oldCap = capacity;
	vector<hashItem> oldArr = data;
	
	data.resize(getPrime(2*oldCap));
	capacity = data.size();
	int r;
	
	for(int i =0; i<capacity; i++)
	{
		data.at(i).setOcc(false);
		data.at(i).setKey("");
	}
		
		
	filled = 0;
	for(int j =0;j<oldCap; j++)
		if(oldArr[j].occupied())
		{
			r = insert(oldArr[j].getKey());
			if(r != 0)
				return false;
		}
				
	return true;
}

static unsigned int hashTable::getPrime(int size)
{
	int pow = 2;
	int ind = 0;

	while(size > pow)
	{
		pow*=2;
		ind++;
	}
	if(ind>21)
		return NULL;
	
	return primes[ind];
}


string strToLower(string str)
{
	for(int i =0; i<str.size(); i++)
		if((int)str[i] >=65 && (int)str[i]<=90)
			str[i]+=32;
			
	return str;
}

vector<string> explode(string del, string str)
{
	vector<string> arr;
	int len = str.length();
	string toput;
	size_t found;
	found = str.find_first_not_of(del);
	
	while(found!=string::npos)
	{
		str[found] = ' ';
		found = str.find_first_not_of(del,found+1);
	}
	
	int k=0;
	size_t fo;
	for(int i= 0; i<len; i++)
	{
		if(str[i] == ' ')
		{
			toput = str.substr(k,i-k); 
			fo = toput.find_first_of("0123456789");
			if(fo == string::npos)
			{
				arr.push_back(toput);		
				k=i+1;
			}
			
		}
	}
	
	if(arr.size() == 0)
		arr.push_back(str);
	else
		arr.push_back(str.substr(k,len-k));
	
	return arr;
}

int main()
{
	hashTable *table = new hashTable();
	int k;
	int cap=0;

	string line;
	string word;
	string temp;
	char file[50];
	char file2[50];
	char ofile[50]; 
	
	cout << "Enter name of dictionary: ";
	cin >>  file;
	

	fstream myfile;
	myfile.open(file);
	
	size_t found;
	string str,word1;
	int i=0;
	
	//read files into hashtable
	clock_t t1 = clock();
	if (myfile.is_open())
	{
		while (! myfile.eof() )
		{
			getline (myfile,line);
			if(line.size()<21)
			{
				str = strToLower(line);
				found=str.find_first_not_of("abcdefghijklmnopqrstuvwxyz0123456789'-\n");
				if (!(found!=string::npos))
					k = (*table).insert(str);
					
				
				if(k!=0)
					continue;
			}
		}
		myfile.close();
	}
	else
		cout<<"unable to open file"<<endl;
	clock_t t2 = clock();
	double timeDiff1 = ((double) (t2 - t1)) / CLOCKS_PER_SEC;
	
	cout<<"Total time (in seconds) to load dictionary: "<<timeDiff1<<endl;
	
	cout << "Enter name of input file: ";
	cin >>  file2;
	cout<<"Enter name of output file: ";
	cin>> ofile;
	ofstream file_op(ofile);
	
	int lijn =1;
	fstream myfile2;
	myfile2.open(file2);
	vector<string> arr;
	clock_t t3 = clock();
	if (myfile2.is_open())
	{
		while (! myfile2.eof())
		{
			getline(myfile2,line);
			arr = explode("abcdefghijklmnopqrstuvwxyz0123456789'-\n",strToLower(line)); 
			
																		
			for(int l = 0; l<arr.size(); l++)
			{
				if(arr[l].size() <21)
				{
					if(!(*table).contains(arr[l]))
						file_op<<"Unknown word at line "<<lijn<<": "<<arr[l]<<endl;
				}
				else
					file_op<<"Long word at line "<<lijn<<", starts: "<<arr[l].substr(0,20)<<endl;
			}
			lijn++;
		}
		myfile2.close();
	}
	else
		cout<<"unable to open file"<<endl;
	clock_t t4 = clock();
	double timeDiff2 = ((double) (t4 - t3)) / CLOCKS_PER_SEC;
	
	cout<<"Total time (in seconds) to check document: "<<timeDiff2<<endl;
			
}

and this is what cygwin has to say on the matter:

hash1.cpp: In member function `void* hashTable::getPointer(const std::string&, b
ool*)':
hash1.cpp:38: error: no matching function for call to `hashTable::hashItem::hash
Item(const std::basic_string<char, std::char_traits<char>, std::allocator<char>
>&, bool*&)'
hash.h:51: note: candidates are: hashTable::hashItem::hashItem()
hash.h:51: note: hashTable::hashItem::hashItem(const hashTable::
hashItem&)
hash1.cpp:43: error: `class hashTable::hashItem' has no member named `setPt'
hash1.cpp:48: error: `class hashTable::hashItem' has no member named `setPt'
hash1.cpp: In member function `int hashTable::insert(const std::string&, void*)'
:
hash1.cpp:65: error: no matching function for call to `hashTable::hashItem::hash
Item(std::string&, void*&)'
hash.h:51: note: candidates are: hashTable::hashItem::hashItem()
hash.h:51: note: hashTable::hashItem::hashItem(const hashTable::
hashItem&)
hash1.cpp:66: error: `class hashTable::hashItem' has no member named `occupied'
hash1.cpp:75: error: `class hashTable::hashItem' has no member named `setOcc'
hash1.cpp: In member function `bool hashTable::remove(const std::string&)':
hash1.cpp:99: error: `class hashTable::hashItem' has no member named `setDel'
hash1.cpp:100: error: `class hashTable::hashItem' has no member named `setOcc'
hash1.cpp: At global scope:
hash1.cpp:133: error: prototype for `hashTable::hashItem::hashItem(const std::st
ring&, void*)' does not match any in class `hashTable::hashItem'
hash.h:51: error: candidates are: hashTable::hashItem::hashItem(const hashTable:
:hashItem&)
hash.h:51: error: hashTable::hashItem::hashItem()
hash.h:51: error: `class hashTable::hashItem' is private
hash1.cpp:133: error: within this context
hash1.cpp:141: error: no `std::string hashTable::hashItem::getKey()' member func
tion declared in class `hashTable::hashItem'
hash.h:51: error: `class hashTable::hashItem' is private
hash1.cpp:141: error: within this context
hash1.cpp:146: error: no `bool hashTable::hashItem::occupied()' member function
declared in class `hashTable::hashItem'
hash.h:51: error: `class hashTable::hashItem' is private
hash1.cpp:146: error: within this context
hash1.cpp:150: error: no `bool hashTable::hashItem::deleted()' member function d
eclared in class `hashTable::hashItem'
hash.h:51: error: `class hashTable::hashItem' is private
hash1.cpp:150: error: within this context
hash1.cpp:154: error: no `void* hashTable::hashItem::getPt()' member function de
clared in class `hashTable::hashItem'
hash.h:51: error: `class hashTable::hashItem' is private
hash1.cpp:154: error: within this context
hash1.cpp:158: error: no `void hashTable::hashItem::setKey(std::string)' member
function declared in class `hashTable::hashItem'
hash.h:51: error: `class hashTable::hashItem' is private
hash1.cpp:158: error: within this context
hash1.cpp:162: error: no `void hashTable::hashItem::setDel(bool)' member functio
n declared in class `hashTable::hashItem'
hash.h:51: error: `class hashTable::hashItem' is private
hash1.cpp:162: error: within this context
hash1.cpp:166: error: no `void hashTable::hashItem::setOcc(bool)' member functio
n declared in class `hashTable::hashItem'
hash.h:51: error: `class hashTable::hashItem' is private
hash1.cpp:166: error: within this context
hash1.cpp:170: error: no `void hashTable::hashItem::setPt(void*)' member functio
n declared in class `hashTable::hashItem'
hash.h:51: error: `class hashTable::hashItem' is private
hash1.cpp:170: error: within this context
hash1.cpp: In member function `int hashTable::findPos(const std::string&)':
hash1.cpp:208: error: `class hashTable::hashItem' has no member named `occupied'

hash1.cpp:208: error: `class hashTable::hashItem' has no member named `getKey'
hash1.cpp:217: error: `class hashTable::hashItem' has no member named `getKey'
hash1.cpp:217: error: `class hashTable::hashItem' has no member named `deleted'
hash1.cpp: In member function `bool hashTable::rehash()':
hash1.cpp:234: error: `class hashTable::hashItem' has no member named `setOcc'
hash1.cpp:235: error: `class hashTable::hashItem' has no member named `setKey'
hash1.cpp:241: error: `class hashTable::hashItem' has no member named `occupied'

hash1.cpp:243: error: `class hashTable::hashItem' has no member named `getKey'
hash1.cpp: At global scope:
hash1.cpp:255: error: cannot declare member function `static unsigned int hashTa
ble::getPrime(int)' to have static linkage
make: *** [hash1.o] Error 1


thanks again

Several similar errors. Since you are not using using namespace std; then you need to specify std:: namespace wherever STL objects are declared, such as in the hashItem class hashItem(const std::string &k, void *pt = NULL); >>static unsigned int hashTable::getPrime(int size
Remove the static keyword in the implementation file. Its only used in the header file.

>>int primes [21] = {3, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169};

Move that line from the header file to the *.cpp implementation file. In the header file just put this: extern int primes[];

Edited 6 Years Ago by Ancient Dragon: n/a

This article has been dead for over six months. Start a new discussion instead.