<html>

<head><script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- MyFirstUnitAd -->
<ins class="adsbygoogle"
     style="display:inline-block;width:970px;height:250px"
     data-ad-client="ca-pub-5778386704669218"
     data-ad-slot="1503492166"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>

<meta http-equiv="Content-Language" content="zh-cn">
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 5.0">
<meta name="ProgId" content="FrontPage.Editor.Document">
<title>Population</title>
</head>

<body>



<p align="left"><font size="6" color="#FF0000"><b>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
New WordReader--a base for parser</b></font></p>

<div align="left">
  <pre><b><font color="#ff0000" size="5">A.<span lang="en-ca"> </span>First Edition</font></b></pre>
</div>
<div align="left">
  <pre><b>This is <span lang="en-ca">my </span>second<span lang="en-ca"> edition of </span>my word reader and I create two utility class---string and strings which is what </b></pre>
</div>
<div align="left">
  <pre><b>I used in Delphi.</b></pre>
</div>
<div align="left">
  <pre><b><font color="#ff0000" size="5"><span lang="en-ca">B</span>.<span lang="en-ca"><a name="problem"></a>The problem</span></font></b></pre>
</div>
<div align="left">
  <b><font size="2">A parser need to read all symbols and this requires a 
  word-reader.</font></b></div>
<div align="left">
  　</div>
<div align="left">
  　</div>
<div align="left">
  <b><font color="#ff0000" size="5"><span lang="en-ca">C</span>.<span lang="en-ca">The
  </span></font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>idea of 
  program</b></font></span></div>
<div align="left">
  <pre><b>A string is a word and strings are words, a wordReader class is simply a file opener and word checker.</b>
</pre>
</div>
<div align="left">
  <pre><b><font size="5" color="#FF0000">D.<span lang="en-ca"><a name="Method"></a>The </span>major functions</font></b></pre>
</div>
<div align="left">
  <pre><span lang="en-ca"><font size="5" color="#FF0000"><b>E</b></font></span><b><font color="#ff0000" size="5">.</font></b><span lang="en-ca"><font size="5" color="#FF0000"><b>Further improvement</b></font></span></pre>
</div>
<div align="left">
  <pre><b>1.<span lang="en-ca"> </span></b><span lang="en-ca"><b>There is trade off for OOP as it slows down program execution by too many object operations. </b></span></pre>
</div>
<pre>　</pre>
<pre><b><font color="#FF0000" size="3">//file string.h
</font></b>
</pre>
<pre>#ifndef STRING_H
#define STRING_H
#include &lt;iostream&gt;

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

#endif</pre>
<pre><b><font size="3" color="#FF0000">//file string.cpp</font></b></pre>
<pre>#include &lt;iostream&gt;
#include &quot;String.h&quot;

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&lt;&lt;&quot;Unable to allocate memory!&quot;&lt;&lt;endl;
		return false;
	}
}


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

//using safe mode for assignment
const String&amp; 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&amp; S)
{
	return strcmp(text, S.getText())==0;
}

String::~String()
{
	len = 0;
	delete[] text;
}</pre>
<pre><b><font size="3" color="#FF0000">//file strings.h</font></b></pre>
<pre>#ifndef STRINGS_H
#define STRINGS_H

#include &lt;iostream&gt;
#include &quot;String.h&quot;

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</pre>
<pre><font color="#FF0000" size="3"><b>//file strings.h</b></font></pre>
<pre>#include &lt;iostream&gt;
#include &quot;Strings.h&quot;

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&gt;lo)
	{
		if (strcmp(str, texts[index]-&gt;getText())&gt;0)
		{
			lo = index+1;		
		}
		else
		{
			if (strcmp(str, texts[index]-&gt;getText())&lt;0)
			{
				hi = index;
			}
			else
			{
				return index;
			}
		}
		index = (hi+lo)/2;
	}
	return index;
}

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

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

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

bool Strings::addStr(const char* str)
{
	int index = locateStr(str);
	if (index &lt; counter)//to make it safe to be within bounds of array
	{
		if (strcmp(str, texts[index]-&gt;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]-&gt;getText())==0)
		{
			delete texts[index];
			for (int i=index; i&lt;counter-1; i++)
			{
				texts[i] = texts[i+1];
			}
			counter--;
			return true;
		}
	}
	return false;
}

void Strings::clearAll()
{
	for (int i=0; i&lt;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&gt;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&lt;counter; i++)
		{
			texts[i] = oldPtr[i];
		}
		return true;
	}
	else
	{
		texts = oldPtr;
		return false;
	}
}
	</pre>
<pre><b><font size="3" color="#FF0000">//file wordreader.h
</font></b></pre>
<pre>#ifndef WORDREADER_H
#define WORDREADER_H

#include &quot;Strings.h&quot;


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

#endif</pre>
<pre>　</pre>
<pre><b><font size="3" color="#FF0000">//file wordreader.h</font></b></pre>
<pre>#include &lt;iostream&gt;
#include &quot;WordReader.h&quot;

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, &quot;r&quot;);
	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&gt;='A'&amp;&amp;ch&lt;='Z') || (ch&gt;='a'&amp;&amp;ch&lt;='z'))
		{
			return true;
		}	
	}
	else
	{
		if ((ch&gt;='A'&amp;&amp; ch&lt;='Z') || (ch&gt;='a'&amp;&amp;ch&lt;='z') 
			|| (ch&gt;='0'&amp;&amp;ch&lt;='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&gt;0)
		{
			buffer[wordLen] = '\0';
			words.addStr(buffer);
		}
	}
}


<b><font color="#FF0000" size="3">//file driver.cpp
</font></b>
</pre>
<pre>#include &lt;iostream&gt;
#include &quot;WordReader.h&quot;

using namespace std;

int main()
{
	WordReader W(&quot;c:\\nickReader.txt&quot;);
//	W.readFile();
	W.printWords();
	cout&lt;&lt;&quot;\nTotal words are &quot;&lt;&lt;W.getCount()&lt;&lt;endl;
	return 0;
}</pre>
<pre>
	</pre>
<pre></pre>
<pre>
</pre>
<pre></pre>
<pre></pre>
<pre></pre>
<pre><b><font color="#FF0000" size="3"><span lang="en-ca"><a name="result"></a>Running result of program:</span></font></b></pre>
<pre></pre>
<pre>　</pre>
<pre>	</pre>
<pre></pre>
<pre>			
</pre>

<pre></pre>

<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                   
&nbsp;&nbsp;&nbsp; <a href="WhoAmI.htm">                  







                       <img src="picture/back.gif" style="border: medium none" alt="back.gif (341 bytes)" width="32" height="35"></a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
<a href="index.htm"><img src="picture/up.gif" style="border: medium none" alt="up.gif (335 bytes)" width="35" height="32"></a>       &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                         
<img src="picture/next.gif" style="border: medium none" alt="next.gif (337 bytes)" width="32" height="35">          


</p>

</body>

</html>