Population

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:

    ¡¡