Ok so i am writing a program for class and I am not very familure with the ways of c++. I have looked into char arrays and can not figure out the issue. It seems like when allocating the space the null terminator is not assigned in the desired location.
My issue is this. I am allocating an array see below:
char* St ="";
if(P.GetSize() > 0)
{
int StLen = P.GetSize() + 1;
St= new char[StLen];
int i;
for( i = 0;!P.isEmpty() && i < (int)strlen(St); i++)//StLen
{
*(St+i)= P.getTop();
P.Pop();
}
*(St+i) = 0;
std::reverse( St, &St[ strlen( St ) ] ); //flip string to display bottom to top
}
if P.GetSize() is 1 and I add one for the null terminator the line (int)strlen(St) is still returning 16 for the length which is the original length of my array read in. I have posted My working Program Below for reference for other people that have the same issue
Below Is my working solution Header File:
//Created By : Timothy Newport
//Created on : 4/26/2012
//===========================================
// NewportStack.h
//============================================
#pragma once
#include <iostream>
#include <iomanip>
#include <fstream>
#include <crtdbg.h>
#include <stack>
#include <string>
using namespace std;
const int MAX_POSTFIX = 30;
void infixToPostfix(const char *infix, char* postfix,ostream& os);
void WriteHeader(ostream& os);
void WriteResults(ostream& os,const char *postfix);
template<class T>
struct Node
{
T data;
Node<T> *prev;
};
template<class T>
class NewportStack
{
private:
Node<T> *top;
int size;
public:
NewportStack();
NewportStack(const NewportStack <T> & displayStack);
~NewportStack();
void Push(T ch);
void Pop();
T getTop() const;
bool isEmpty() const;
const int GetSize() const;
int SetSize(const int prvSize);
bool checkPresidence(T data,char infix);
void printStack() const;
virtual ostream& Output (ostream& os, const NewportStack & S,
const char infix,const char *postfix
,const int size) const;
};
//------------
//Constructor
//------------
template<class T>
NewportStack<T>::NewportStack()
{
top = NULL;
size = 0;
}
template<class T>
void NewportStack<T>::printStack() const
{
Node<T>* w;
w = top;
while( w != NULL )
{
cout << w->data;
w = w->prev;
}
}
//------------
//Copy Constructor
//------------
template<class T>
NewportStack<T>::NewportStack(const NewportStack<T> &Orig)
{
if (Orig.top == NULL) // check whether original is empty
{
top = NULL;
}
else
{
Node<T>* newPrev=new Node<T> ;
Node<T>* cur = Orig.top;
newPrev->data = cur->data;
top = newPrev;
// Now, loop through the rest of the stack
cur = cur->prev;
while(cur != NULL )
{
newPrev->prev = new Node<T>;
newPrev = newPrev->prev;
newPrev->data = cur->data;
cur = cur->prev;
} // end for
newPrev->prev = 0;
cur = 0;
} // end else
size = Orig.size;
} // end copy constructortor
//------------
//DeConstructor
//------------
template<class T>
NewportStack<T>::~NewportStack()
{
Node <T>* w = top;
while(top!=NULL)
{
delete w;
top=top->prev;
}
size =0;
}
//------------
//getsize
//------------
template<class T>
const int NewportStack<T>::GetSize() const
{
return size;
}
//------------
//SetSize
//------------
template<class T>
int NewportStack<T>::SetSize(const int prvSize)
{
return size = prvSize;
}
//------------
//Push
//------------
template<class T>
void NewportStack<T>::Push(T d)
{
Node <T>* w= new (std::nothrow) Node<T>;
if ( !w )
{
cerr << "Error out of memory in Push\n";
exit (1);
}
w->data =d;
if( top == NULL )
{
w->prev = NULL;
}
else
{
w->prev = top;
}
top = w;
w = NULL;
size++;
}
//------------
//Pop
//------------
template<class T>
void NewportStack<T>::Pop()
{
if( top == NULL )
return;
Node<T>* w = top;
top = top->prev;
delete w;
w = NULL;
size--;
}
//------------
//getTop
//------------
template<class T>
T NewportStack<T>::getTop() const
{
if (isEmpty ())
exit(0);
return top->data;
}
//------------
//isEmpty
//------------
template<class T>
bool NewportStack<T>::isEmpty() const
{
if(top == NULL)
{
return true;
}
return false;
}
//------------
//checkPresidence
//------------
template<class T>
bool NewportStack<T>::checkPresidence(T data,char infix)
{
switch(infix)
{
case '+': case '-':
switch(data)
{
case '+': case '-': case '*': case '/': case '%':
return true;
default: return false;
}
case '*': case '/': case '%':
switch(data)
{
case '*': case '/': case '%':
return true;
default: return false;
}
default: return false;
}
}
//------------
//OutPut
//------------
template<class T>
ostream& NewportStack<T>::Output(ostream& os, const NewportStack<T>& S,
const char infix,const char *postfix
,const int size) const
{
NewportStack<T> P ( S );//***INVOKED COPY CONSTRUCTOR*****
char* St = new char[21];
int i;
if(P.GetSize() > 0)
{
int StLen = P.GetSize();
for( i = 0;!P.isEmpty();i++)
{
*(St+i)= P.getTop();
P.Pop();
}
*(St+i) = 0;
std::reverse( St, &St[ strlen( St ) ] ); //flip string to display bottom to top
}
else
*(St+0) = 0;
os <<left<<setw(20) << infix ;
for(i = 0;i < (int)strlen(St);i++)
{
os << St[i];
}
os << right<< setw(21-i);
for(i = 0;i <size;i++)
{
os << postfix[i];
}
os << endl;
if(St != NULL)
{
delete[] St;
}
return os;
}
CPP File Here:
//Created By : Timothy Newport
//Created on : 4/26/2012
//===========================================
// NewportStackTester.cpp
//============================================
#include "NewportStack.h"
//------------
//Main
//------------
int main()
{
//////////////////////////////////////////
/// Tester Part Two Test The class ///
//////////////////////////////////////////
char arr[] = "a+b-c*d/e+(f/g/h-a-b)/(x-y)*(p-r)+d";
//char arr[] = "a+b-c*d/e+(f/g)";
int len = (int) strlen(arr);
char *postfix = new char[len+1];
ofstream outputFile;
outputFile.open("PostFix.txt");
outputFile << "Infix is : " << arr<<endl<<endl;
WriteHeader(outputFile);
_strupr( arr); ///**** convert the string to uppercase ****
infixToPostfix(arr,postfix,outputFile);
outputFile.close();
system("notepad.exe PostFix.txt");
return 0;
}
//------------
//infixToPostfix
//------------
void infixToPostfix(const char *infix, char* postfix, ostream & os)
{
NewportStack <char> P;
int len=strlen(infix);
len += 1;
// cout << "infix in infixToPostfix: " << infix << endl;
int pi = 0;
int i=0;
char ch;
while( i < len && *(infix+i) !='\0')
{
ch = *(infix+i);
if(ch >='A' && ch <='Z' )
{
postfix[pi++]= ch;
}
else if(ch =='+' ||ch =='-'||ch =='*'||ch =='/'||ch =='%')
{
while(!P.isEmpty() && P.getTop() != '('
&& P.checkPresidence(P.getTop(), ch ) )
{
postfix[pi++]= P.getTop();
postfix[pi] = 0;
P.Pop();
}
P.Push(ch);
}
else if(infix[i] == '(')
{
P.Push(infix[i]);
}
else// if(infix[i]==')')
{
while(!P.isEmpty() && P.getTop() != '(')
{
postfix[pi++] = P.getTop();
P.Pop();
}
P.Pop(); //****remove the '(' from the stack top.
}
P.Output(os, P, ch, postfix, pi); // display after each read
i++;
}
// end of infix empty stack
while(!P.isEmpty() )
{
postfix[pi++]= P.getTop();
P.Pop();
}
postfix[pi] = 0; //add null terminator at the end of the string.
//cout << "postfix 104: " << postfix << endl;
P.Output(os,P,*infix,postfix,pi);// display final line
WriteResults(os,postfix);
}
//------------
//WriteHeader
//------------
void WriteHeader(ostream& os)
{
os <<left<< setw(20)<< "Input Characters" << setw(20)<< "Stack Item" << setw(20)
<< "PostFix" <<endl <<setw(20)<< "----------------"<< setw(20)
<< "----------" << setw(20)<< "-------" <<endl;
}
//------------
//WriteResults
//------------
void WriteResults(ostream& os,const char *postfix)
{
os << endl<< "The Final postfix is: " << postfix <<endl;
}
You folks help me so much! I just kept messing around with it until I found the issue in the main.