Ok, I got the Size function working.
I changed the code a bit, after reading through your logic some.
The problem was in Size, where you attempted to initialize countPtr to be the rear and compare it to the front.
You're traversing from the low end of the list and further towards lower parts without ascending upwards, so the loop is infinite and will never reach frontPtr.
Here are the changes I made--
#ifndef TEMPLATEQ_H
#define TEMPLATEQ_H
#include <iostream>
#include <new>
#include <cstddef>
using namespace std;
class FullTemplateQ // Exception class
{};
class EmptyTemplateQ // Exception class
{};
template<class SomeType> // Node template class
struct QueueNode
{
SomeType data; // Data stored in queue node
QueueNode<SomeType>* nextPtr; // Pointer to next queue node
};
template<class SomeType> // Circular queue template class
class TemplateQ
{
private:
QueueNode<SomeType>* rearPtr; // Pointer to rear of queue
QueueNode<SomeType>* frontPtr; // Pointer to front of queue
void PrintNext(QueueNode<SomeType>* tempPtr) const; // Print trailing items
public:
TemplateQ(); // Default constructor
~TemplateQ(); // Destructor deallocates every node
void Enqueue(SomeType newData); // Adds newdata node to rear of queue
SomeType Dequeue(); // Removes data node from front of queue,
// returning the stored data
bool IsFull() const; // Returns true if queue is full,
// false otherwise
bool IsEmpty() const; // Returns true if queue is empty,
// false otherwise
int Size() const; // Returns the number of items in queue
void ForwardPrint() const; // Prints queue, front to rear
void ReversePrint() const; // Prints queue, rear to front
};
#include "templateq.cpp" // Very Important!! Do not delete!!
#endif
#ifdef TEMPLATEQ_H
#include <new>
#include <cstddef>
#include <iostream>
//There is no need for #include "templateq.h" since the header file has #include "templateq.cpp" at the end of it.
using namespace std;
template<class SomeType>
TemplateQ<SomeType>::TemplateQ()
{
frontPtr = NULL;
rearPtr = NULL;
}
template<class SomeType>
void TemplateQ<SomeType>::Enqueue(SomeType newData)
{
if (IsFull())
throw FullTemplateQ();
else
{
QueueNode<SomeType>* nextQueueLocation = NULL;
nextQueueLocation = new QueueNode<SomeType>;
nextQueueLocation->data = newData;
nextQueueLocation->nextPtr = NULL;
if(rearPtr == NULL)
frontPtr = nextQueueLocation;
else
rearPtr->nextPtr = nextQueueLocation;
rearPtr = nextQueueLocation;
}
}
template<class SomeType>
bool TemplateQ<SomeType>::IsFull()const
{
QueueNode<SomeType>* tempPtr = NULL;
try
{
tempPtr = new QueueNode<SomeType>;
delete tempPtr;
return false;
}
catch (std::bad_alloc)
{
return true;
}
}
template<class SomeType>
bool TemplateQ<SomeType>::IsEmpty()const
{
return (frontPtr == NULL);
}
template<class SomeType>
int TemplateQ<SomeType>::Size() const
{
int numberOfChars = 0;
QueueNode<SomeType>* countPtr = frontPtr;
if(IsEmpty())
return 0;
while(countPtr != NULL)
{
//countPtr = rearPtr->nextPtr;
countPtr = countPtr->nextPtr;
numberOfChars ++;
}
return numberOfChars;
}
template<class SomeType>
void TemplateQ<SomeType>::ForwardPrint()const
{
QueueNode<SomeType>* countPtr = NULL;
if(IsEmpty())
throw EmptyTemplateQ();
else
{
countPtr = frontPtr;
while(countPtr != rearPtr)
{
countPtr = countPtr->data;
cout << countPtr->data << " ";
countPtr = countPtr->nextPtr;
}
cout << endl;
}
}
template<class SomeType>
void TemplateQ<SomeType>::ReversePrint()const
{}
template<class SomeType>
SomeType TemplateQ<SomeType>::Dequeue()
{
QueueNode<SomeType>* dequeuePtr = NULL;
if(IsEmpty())
throw EmptyTemplateQ();
else
{
dequeuePtr = frontPtr;
//dequeuePtr = frontPtr->data;
frontPtr = frontPtr->nextPtr;
if(frontPtr == NULL)
rearPtr = NULL;
}
return dequeuePtr->data;
delete dequeuePtr;
}
template<class SomeType>
TemplateQ<SomeType>::~TemplateQ()
{
QueueNode<SomeType>* tempPtr = NULL;
while (frontPtr != NULL)
{
tempPtr = frontPtr;
frontPtr = frontPtr->nextPtr;
delete tempPtr;
}
rearPtr = NULL;
}
#endif
#include "templateq.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
#include <cmath>
#include <cstddef>
#include <new>
int main(int argc, char * const argv[])
{
char command, letter;
TemplateQ<char> queue;
ifstream inputs;
//if (argc !=2)
//{
cout << "Usage:\n program06 <inputfile>\n";
// return 1;
//}
//inputs.open(argv[1]);
inputs.open("C:/MyFile.txt");
if(!inputs)
{
cout << "Unable to open file" << endl;
return 1;
}
inputs >> command;
// if(command != 'c')
// {
// cout << "Invalid File Format - missing 'c'\nTerminating program now..." << endl;
// return 1;
// }
while(!inputs.eof())
{
switch(command)
{
case 'c':
{
cout << "Constructor()" << endl;
break;
}
case '+':
{
try
{
inputs >> letter;
//cout << letter << endl;
cout << "Enqueue('";
queue.Enqueue(letter);
cout << letter << "')"<< endl;
}
catch(FullTemplateQ)
{
cout << "Failed Full Queue" << endl;
}
break;
}
case '-':
{
try
{
cout << "Dequeue() -- ";
queue.Dequeue();
cout << queue.Dequeue() << endl;
}
catch(EmptyTemplateQ)
{
cout << "Failed Empty Queue" << endl;
}
break;
}
case 'p':
{
cout << "case p" << endl;
break;
}
case 'r':
{
cout << "case r" << endl;
break;
}
case 's':
{
cout << "Size () -- " << queue.Size() << endl;
break;
}
case 'd':
{
queue.~TemplateQ();
cout << "Destructor ()" << endl;
break;
}
default:
{
cout << "Command not recognized" << endl;
}
}
inputs >> command;
}
cin.ignore();
cin.get();
return 0;
}
The file I used ("C:/MyFile.txt")--
c
s
+
a
+
b
+
c
+
d
+
e
+
f
p
r
s
Instead of initializing countPtr in size to point to rear, I made it point to the front and simply traverse down the queue.