New WordReader--a base for parser

A. First Edition
This is my second edition of my word reader and I create two utility class---string and strings which is what 
I used in Delphi.
B.The problem
A parser need to read all symbols and this requires a word-reader.
 
 
C.The idea of program
A string is a word and strings are words, a wordReader class is simply a file opener and word checker.
D.The major functions
E.Further improvement
1. There is trade off for OOP as it slows down program execution by too many object operations. 
 
//file string.h

#ifndef STRING_H
#define STRING_H
#include <iostream>

class String
{
private:
	char* text;
	int len;
	bool internalCopy(const char* str);
public:
	const String& operator=(const char*);
	String(const String& S);//copy constructor
	bool operator==(const String& S);
	const int length() const {return len;}
	String(const char*);
	~String();
	const char* getText() const { return text;}
};

#endif
//file string.cpp
#include <iostream>
#include "String.h"

using namespace std;

String::String(const char* str)
{
	internalCopy(str);
}

bool String::internalCopy(const char* str)
{
	len = strlen(str);
	text = new char[len+1];
	if (text!=NULL)
	{
		strcpy(text, str);
		return true;
	}
	else
	{
		cout<<"Unable to allocate memory!"<<endl;
		return false;
	}
}


String::String(const String& S)
{
	internalCopy(S.getText());
}

//using safe mode for assignment
const String& String::operator =(const char* str)
{
	char* oldPtr = text;
	int oldLen = len;
	if (internalCopy(str))
	{
		delete[] oldPtr;
	}
	else
	{
		text = oldPtr;
		len = oldLen;
	}
	return *this;
}

bool String::operator ==(const String& S)
{
	return strcmp(text, S.getText())==0;
}

String::~String()
{
	len = 0;
	delete[] text;
}
//file strings.h
#ifndef STRINGS_H
#define STRINGS_H

#include <iostream>
#include "String.h"

const int Increment = 20;

class Strings
{
private:
	String** texts;
	int counter;
	bool expand();
	bool insertStr(String* strPtr, int index);
public:
	Strings();
	const int getCount() const { return counter;}
	bool addStr(const char* str);
	bool findStr(const char* str);
	int locateStr(const char* str);
	bool deleteStr(const char* str);
	void clearAll();
	void printWords();
	~Strings();
};

#endif
//file strings.h
#include <iostream>
#include "Strings.h"

using namespace std;


Strings::Strings()
{
	counter =0;
	texts = NULL;
}

//return value is just index number bigger than the str
int Strings::locateStr(const char* str)
{
	int index, hi=counter, lo=0;
	index = (hi+lo)/2;

	while (hi>lo)
	{
		if (strcmp(str, texts[index]->getText())>0)
		{
			lo = index+1;		
		}
		else
		{
			if (strcmp(str, texts[index]->getText())<0)
			{
				hi = index;
			}
			else
			{
				return index;
			}
		}
		index = (hi+lo)/2;
	}
	return index;
}

void Strings::printWords()
{
	for (int i=0; i< counter; i++)
	{
		cout<<texts[i]->getText()<<endl;
	}
}

bool Strings::findStr(const char* str)
{
	int index = locateStr(str);
	if (index==counter)
	{
		return false;
	}

	return strcmp(str, texts[index]->getText())==0;
}

bool Strings::addStr(const char* str)
{
	int index = locateStr(str);
	if (index < counter)//to make it safe to be within bounds of array
	{
		if (strcmp(str, texts[index]->getText())==0)
		{
			return false;
		}
	}

	String* strPtr = new String(str);
	return insertStr(strPtr, index);
}

bool Strings::deleteStr(const char* str)
{
	int index = locateStr(str);
	if (index == counter)
	{
		return false;//cannot find str
	}
	else
	{
		if (strcmp(str, texts[index]->getText())==0)
		{
			delete texts[index];
			for (int i=index; i<counter-1; i++)
			{
				texts[i] = texts[i+1];
			}
			counter--;
			return true;
		}
	}
	return false;
}

void Strings::clearAll()
{
	for (int i=0; i<counter; i++)
	{
		delete texts[i];
	}
	delete [] texts;
	counter = 0;
}


Strings::~Strings()
{
	clearAll();
}


bool Strings::insertStr(String* strPtr, int index)
{
	if (counter%Increment==0)
	{
		if (!expand())
		{
			return false;		
		}	
	}
	for (int i=counter; i>index; i--)//move one position forwards
	{
		texts[i] = texts[i-1];				
	}
	texts[index] = strPtr;
	counter++;
	return true;
}

bool Strings::expand()
{
	String** oldPtr = texts;
	texts = new String*[counter+Increment];
	if (texts!=NULL)
	{
		for (int i=0; i<counter; i++)
		{
			texts[i] = oldPtr[i];
		}
		return true;
	}
	else
	{
		texts = oldPtr;
		return false;
	}
}
	
//file wordreader.h
#ifndef WORDREADER_H
#define WORDREADER_H

#include "Strings.h"


class WordReader
{
private:
	Strings words;
	void doReading(FILE* stream);
	bool checkChar(char ch, int index);
public:
	WordReader(const char* fileName = "c:\\nick.txt");
	void printWords();
	void readFile(const char* fileName);
	const int getCount() const { return words.getCount();}
};

#endif
 
//file wordreader.h
#include <iostream>
#include "WordReader.h"

using namespace std;


const int MaxWordLength = 20;

WordReader::WordReader(const char* fileName)
{
	readFile(fileName);
}

void WordReader::readFile(const char* fileName)
{
	FILE* stream;
	stream = fopen(fileName, "r");
	if (stream!=NULL)
	{
		doReading(stream);
	}
}

void WordReader::printWords()
{
	words.printWords();
}

//the principle of symbol
bool WordReader::checkChar(char ch, int index)
{
	if (index==MaxWordLength)
	{
		return false;
	}
	if (index==0)
	{
		if ((ch>='A'&&ch<='Z') || (ch>='a'&&ch<='z'))
		{
			return true;
		}	
	}
	else
	{
		if ((ch>='A'&& ch<='Z') || (ch>='a'&&ch<='z') 
			|| (ch>='0'&&ch<='9') || (ch == '_'))
		{
			return true;
		}
	}
	return false;
}
			



void WordReader::doReading(FILE* stream)
{
	char ch;
	int wordLen;
	char buffer[MaxWordLength+1];
	while (!feof(stream))
	{
		ch = getc(stream);
		wordLen = 0;
		while (checkChar(ch, wordLen))//chop off 
		{
			buffer[wordLen] = ch;
			wordLen++;
			if (feof(stream))
			{
				//write last word
				buffer[wordLen] = '\0';
				words.addStr(buffer);
				return;
			}
			
			ch = getc(stream);
		}
		if (wordLen>0)
		{
			buffer[wordLen] = '\0';
			words.addStr(buffer);
		}
	}
}


//file driver.cpp

#include <iostream>
#include "WordReader.h"

using namespace std;

int main()
{
	WordReader W("c:\\nickReader.txt");
//	W.readFile();
	W.printWords();
	cout<<"\nTotal words are "<<W.getCount()<<endl;
	return 0;
}
	





Running result of program:

 
	

			


                                 back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)

Hosted by www.Geocities.ws

1