Hello,
I've attached my code, I keep getting the Debug Assertion failed, Expression: string subscript out of range error

I can't find any errors in my logic and code for the functions, but obviously something is wrong, no matter where I put breaks, i still get the error when debugging. Any idea where I should look for the problem.

Attachments
// Specification file for InfixToPostfix.h

#ifndef H_InfixToPostfix
#define H_InfixToPostfix

#include <string>

using namespace std;

class infixToPostfix
{
public:
	void convertToPostfix();
	bool precedence(char opr1, char opr2);
	void getInfix(string);
	void showInfix();
	void showPostfix();
	infixToPostfix(string = ""); //Default constructor
		
private:
	string  ifx;
	string  pfx;
};

#endif
//Implementation File

#include <iostream>
#include <string>
#include "myStack.h"
#include "infixToPostfix.h"

using namespace std;

void infixToPostfix::convertToPostfix()
{
	stackType<char>  oprStack;
	int i;
	char sOpr;

	i = 0;

	pfx = "";

	while (ifx[i] != ';')
	{
		ifx[i] = ifx[i+1];	
		switch (ifx[i])
		{
			case 'A':
			case 'B':
			case 'C':
			case 'D':
			case 'F':
			case 'G':
				pfx += ifx[i++];
				break;
			case ' ':
				break;
			case '^':
				oprStack.push(ifx[i]);
				break;
			case '+':
			case '-':
			case '*':
			case '/':
				while (!oprStack.isEmptyStack() && !precedence(ifx[i], oprStack.top()))
				{
					pfx += oprStack.top();
					oprStack.pop();
				}//end while
				oprStack.push(ifx[i]);
				break;
			case '(':  
				oprStack.push(ifx[i]);
				break;
			case ')':   
				sOpr = oprStack.top();
				oprStack.pop();
				while(sOpr != '(')
				{
					pfx += sOpr;
					if(!oprStack.isEmptyStack())
					{
						sOpr = oprStack.top();
						oprStack.pop();
					}
				}//end while
				break;
			default:
				break;						
		}//end switch
}//end while

	while (!oprStack.isEmptyStack())
	{
		sOpr = oprStack.top();
		pfx += sOpr;
	}//end while
}//end convertToPostfix


bool infixToPostfix::precedence(char opr1, char opr2)
{
	int prec1, prec2;

	if(opr1 == '*' || opr1 =='/')
		prec1 = 2;
	else
		if(opr1 == '+' || opr1 == '-')
			prec1 = 1;
		else
			if(opr1 ='(')
				prec1 = 0;

	if(opr2 == '*' || opr2 == '/')
		prec2 = 2;
	else
		if(opr2 =='+' || opr2 == '-')
			prec2 = 1;

	return(prec1 >= prec2);
}//end precedence

void infixToPostfix::getInfix(string data)
{
	ifx = data;
	convertToPostfix();
}


void infixToPostfix::showInfix()
{
	cout<<"Infix: "<<ifx<<endl;
}


void infixToPostfix::showPostfix()
{
	cout<<"Postfix: "<<pfx<<endl;
}

infixToPostfix::infixToPostfix(string ifx)
{
	ifx = ifx;
	convertToPostfix();
}
A+B-C;
A+B*C;
A*B+C;
(A+B)*C;
(A+B)*(C-D);
A+((B+C)*(E-F)-G)/(H-I);
A+B*(C+D)-E/F*G+H;
// myStack.h; Header file

#ifndef H_StackType
#define H_StackType

#include <iostream>
#include <cassert>

using namespace std;

template<class Type>
class stackType
{
public:
    const stackType<Type>& operator=(const stackType<Type>&); 
		//Overload the assignment operator.
    void initializeStack();
		//Function to initialize the stack to an empty state.
		//Postcondition: stackTop = 0
    bool isEmptyStack();
		//Function to determine whether the stack is empty.
		//Postcondition: Returns true if the stack is empty;
		//               otherwise, returns false.
    bool isFullStack();
		//Function to determine whether the stack is full.
		//Postcondition: Returns true if the stack is full;
		//               otherwise, returns false.
    void destroyStack();
		//Function to remove all the elements from the stack.
		//Postcondition: stackTop = 0

    void push(const Type& newItem);
		//Function to add newItem to the stack.
		//Precondition: The stack exists and is not full.
		//Postcondition: The stack is changed and newItem 
		//               is added to the top of stack.
    Type top();
		//Function to return the top element of the stack.
		//Precondition: The stack exists and is not empty.
 		//Postcondition: If the stack is empty, the program 	
		//               terminates; otherwise, the top element 
		//               of the stack is returned.
    void pop();
		//Function to remove the top element of the stack.
		//Precondition: The stack exists and is not empty.
		//Postcondition: The stack is changed and the top 
		//               element is removed from the stack.

    stackType(int stackSize = 100); 
		//constructor
		//Creates an array of the size stackSize to hold the 
		//stack elements. The default stack size is 100.
		//Postcondition: The variable list contains the base
		//               address of the array, stackTop = 0, and  
		//               maxStackSize = stackSize.
    stackType(const stackType<Type>& otherStack); 
		//copy constructor
    ~stackType(); 
		//destructor
		//Removes all the elements from the stack.
		//Postcondition: The array (list) holding the stack 
		//               elements is deleted.

private:
    int maxStackSize; //variable to store the maximum stack size
    int stackTop;	    //variable to point to the top of the stack
    Type *list; 	    //pointer to the array that holds the
 		          //stack elements

    void copyStack(const stackType<Type>& otherStack); 
 		//Function to make a copy of otherStack.
 		//Postcondition: A copy of otherStack is created and
 		//               assigned to this stack.
};


template<class Type>
void stackType<Type>::initializeStack()
{
	stackTop = 0;
}//end initializeStack

template<class Type>
void stackType<Type>::destroyStack()
{
	stackTop = 0;
}//end destroyStack

template<class Type>
bool stackType<Type>::isEmptyStack()
{
	return(stackTop == 0);
}//end isEmptyStack

template<class Type>
bool stackType<Type>::isFullStack()
{
	return(stackTop == maxStackSize);
} //end isFullStack

template<class Type>
void stackType<Type>::push(const Type& newItem)
{
    if(!isFullStack())
    {
		list[stackTop] = newItem;    //add newItem at the 
 					//top of the stack
		stackTop++;   //increment stackTop
    }
    else
		cerr<<"Cannot add to a full stack."<<endl;
}//end push

template<class Type>
Type stackType<Type>::top()
{
	assert(stackTop != 0);              //if stack is empty, 
 										//terminate the program
	return list[stackTop - 1];			//return the element of the 
										//stack indicated by 
 					  					//stackTop - 1
}//end top

template<class Type>
void stackType<Type>::pop()
{
	if(!isEmptyStack())
	   stackTop--;             //decrement stackTop 
 	else
	   cerr<<"Cannot remove from an empty stack."<<endl;
}//end pop

template<class Type>
stackType<Type>::stackType(int stackSize) 
{
	if(stackSize <= 0)
	{
		cerr<<"Size of the array to hold the stack must "
			<<"be positive."<<endl;
		cerr<<"Creating an array of size 100."<<endl;

		maxStackSize = 100;
	}
	else
		maxStackSize = stackSize;  //set the stack size to 
   				     	   //the value specified by 
 				     	   //the parameter stackSize

	stackTop = 0;				   //set stackTop to 0
	list = new Type[maxStackSize]; //create the array to
  									//hold the stack elements
	assert(list != NULL);
}//end constructor

template<class Type>
stackType<Type>::~stackType() //destructor
{
   delete [] list; //deallocate memory occupied by the array
}//end destructor

template<class Type>
void stackType<Type>::copyStack(const stackType<Type>& otherStack)
{ 

 	delete [] list;				   
	maxStackSize = otherStack.maxStackSize;		   
  	stackTop = otherStack.stackTop;			   
	  
    list = new Type[maxStackSize];		   
	assert(list != NULL);			   

             //copy otherStack into this stack
      for(int j = 0; j < stackTop; j++)  
          list[j] = otherStack.list[j];
} //end copyStack


template<class Type>
stackType<Type>::stackType(const stackType<Type>& otherStack)
{
	list = NULL;

	copyStack(otherStack);
}//end copy constructor

template<class Type>
const stackType<Type>& stackType<Type>::operator=
   					(const stackType<Type>& otherStack)
{ 

   if(this != &otherStack) //avoid self-copy
 	  copyStack(otherStack);

   return *this; 
} //end operator=         

#endif
//Main program infix to postfix

#include <iostream>
#include <fstream>
#include <cstring>
#include "myStack.h"
#include "infixToPostfix.h"

using namespace std;

int main()
{
	infixToPostfix  InfixExp;
	string infix;

	ifstream infile;

	infile.open("input.txt");

	if(!infile)
	{
		cout<<"Cannot open input file. Program terminates!!!"<<endl;
		return 1;
	}

	getline(infile, infix);

	while(infile)
	{
		InfixExp.getInfix(infix);
		InfixExp.showInfix();
		InfixExp.showPostfix();
		cout<<endl;

		getline(infile, infix);
	}

	infile.close();
	cout << "Press Enter to end the program.";
	getchar();
	return 0;
}

I am not going to deal with all the things that are wrong here

They include:

(a) a missing = in a test else if (opr1 ='(')
(b) stupid reassignment ifx[i] = ifx[i+1]; but loop on i.
(c) Failure to initialize variables and then do a test of two uninitialized variables
(d) Assuming a terminator char ( ; ) is in a string BUT then default string doesn't have it (i.e. you use ""). So test for the end of the string as well as the terminator.

However, from the code, with templates etc, you are clearly not a beginner BUT the trivial beginner errrors you are making are :
(It does seem that two different programmers wrote myStack and InfixToPostfix. -- these are the infixtopost problems:)

(i) Not using compiler warnings
(ii) writing using namespace std;
(iii) passing everything by value not reference
(iv) Not using the keyword: const
(v) not initializing variables
(vi) not writing copy/assignment methods for complex classes.
(vii) Breaking the program down into subunits, but not testing them individually.
(viii) using varaible names like ifx, which is a minor typo away from a mess.

Number (ii) is the cause of some of your strange error messages since you use a variable called list. This is only possible IF you got the scoping correct....

The whole point of a namespace is to avoid name pollution so don't take it away.

[Rant]
When I interview programmers I ask them to write a piece of code, and if they put "using namespace std" at the top of their program, they are 99% of the way to the "no hire" bucket because they can't have (a) read much (b) writen much code.
[/Rant]

Finally a bit of maths: A/B*C/D is the same as (A/B)*(C/D). Additionally
A/B/C is not the same as (A*C)/B but the same as (A/C)/B. Fix your precedence function.

Edited 4 Years Ago by Reverend Jim: Fixed formatting

This article has been dead for over six months. Start a new discussion instead.