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...
Now that you posted the code that works, post the code that doesn't work and also a few of the compiler errors.
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, std::allocator
>&, 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 thestatic 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[];