I have a program that is supposed to match opening and closing braces. It's supposed to work like a stack. It works until the last line of the input file. The last line is matching, but because it thinks the array size is zero it drops out and states that it doesn't match. I could really use some help on this. I know this isn't the most efficient way of doing this, but we were to use the list class we had previously created and we aren't allowed to use the built-ins that C++ has to offer. I have been looking at this and just can't see it. Any help, tips, comments, or advice is greatly apppreciated!

Output:
( ) 
Parenthesis matched
[ ] ( ) { } 
Parenthesis matched
[ { ( ) } ] 
Parenthesis matched
[ [ ) ) 
Parenthesis Not matched
{ ( ) [ ( ) ] 
Parenthesis Not matched Quoted Text Here Quoted Text Here



class List
{
      public:
        //Typedef declarations
        typedef char ET;//Element Type
        static const ET CAPACITY = 20; //Size of the array

        List()
        {
            //Set to zero
            Position = 0;
            Used = 0;

            //Zero out array
            for(int i = 0; i < CAPACITY; i++)
            {
                MyAry[i] = 0;
            }
        }

         void front()
        {
            //Sets position to the first location
            Position = 0;
        }

        void end()
        {
            //Gets the end position
            if(Used != 0)
            {
                Position = Used - 1;
            }
        }

        void prev()
        {
            //Subtracts one from current position
            if(Position - 1 >= 0)
            {
                Position--;
            }
        }


        bool empty()
        {
            //Used = 0 is returns true
            return Used;
        }

        void next()
        {
            //Adds one to current position
            if(Position + 1 < Used)
            {
                Position++;
            }
        }

        int getPos()
        {
            //Returns current Position
            return Position + 1;
        }


        void setPos(int NewPos)
        {
            //Sets Position to New Position
            if((NewPos >= 0) && (NewPos < Used))
            {
                Position = NewPos;
            }
        }

        bool insertBefore(ET value)
        {
            //Checks for position out of bounds
            if(Position + 1 > CAPACITY)
            {
                return false;
            }
            else
            {
                //If used is zero then first element
                if(Used == 0)
                {
                    MyAry[Used] = value;
                }
                else
                {
                    //Shuffles everything down to make room for new element
                    for(int i = Used; i > Position; i--)
                    {
                        MyAry[i] = MyAry[i - 1];
                    }
                    MyAry[Position] = value;
                }

                Used++;

                return true;
            }
        }

    ET getElement()
        {
            return MyAry[Position];
        }

        bool insertAfter(ET value)
        {
            //Checks for position out of bounds
            if(Position + 1 > CAPACITY)
            {
                return false;
            }
            else
            {
                //If used is zero then first element
                if(Used == 0)
                {
                    MyAry[Used] = value;
                }
                else
                {
                    //Moves everything down to make room for new element
                    for(int i = Used; i > Position + 1; i--)
                    {
                        MyAry[i] = MyAry[i - 1];
                    }
                    MyAry[Position] = value;
                }

                //Increment
                Position++;
                Used++;

                return true;
            }
        }

        int size()
        {
            //Returns size of the array
            return Used;
        }

        void replace(int RepVal)
        {
            //Replace current value at position with new value
            MyAry[Position] = RepVal;
        }

        void clear()
        {
            //Return the List back to zero
            for(int i = 0; i < CAPACITY; i++)
            {
                MyAry[i] = 0;
            }

            //Return values to zero
            Position = 0;
            Used = 0;
        }

        void erase()
        {
            //Move all remaining elements down
            for(int i = Position; i < Used; i++)
            {
                MyAry[i] = MyAry[i + 1];
            }

            //Decrement Used
            Used--;
        }
             friend ostream &operator<<(ostream &stream,List L);

    private:
        ET MyAry[CAPACITY];
        int Used;
        int Position;

};

ostream &operator<<(ostream &stream,List L)
{
       for(int i=0;i<L.Used;i++)
       {

             stream<<L.MyAry[i]<<" ";
       }
       stream<<endl;
       return stream;
}

//Declare file streams
ifstream inFile;
ofstream outFile;

int main()
  {
    List stack;
    char inputArray[8];
    char value;
    int i=0;
    bool flag=true;

    //Open inFile
    inFile.open("StackStr.txt");

    while(!inFile)
    {
        cout << "Error opening the inFile." << endl;
        return 1;
    }

    //Open outFile
    outFile.open("StackResults.txt");

    while(!outFile)
    {
        cout << "Error opening the outFile." << endl;
        return 1;
    }

    while(inFile)
    {
        inFile.getline(inputArray, 8,'\n');
        i = 0;
        flag = true;

        while(inputArray[i] != '\0')
        {
            value=inputArray[i];
            cout << value << " ";
            outFile << value << " ";
            i++;

            if(value=='(' || value=='[' || value=='{')
                stack.insertBefore(value);
            else if(value==')' || value==']' || value=='}')
            {
                if(stack.size()==0)
                {
                    flag=false;
                    break;
                }
                else
                {
                    stack.front();
                    if((stack.getElement()=='(' && value==')'))
                    {
                        flag=true;
                        stack.erase();
                    }
                    else if((stack.getElement()=='[' && value==']'))
                    {
                        flag=true;
                        stack.erase();
                    }
                    else if((stack.getElement()=='{' && value=='}'))
                    {
                        flag=true;
                        stack.erase();
                    }
                    else
                    {
                        flag=false;
                        cout << value << " ";
                        outFile << value << " ";
                        break;
                    }
                }
            }
        }
        if(stack.size() == 0)
        {
            flag = true;
        }
        else
        {
            flag = false;
        }


        if(flag == true)
        {
            cout<<endl<<"Parenthesis matched" << endl;
            outFile<<endl<<"Parenthesis matched" << endl;
        }
        else
        {
            cout<<endl<<"Parenthesis Not matched" << endl;
            outFile<<endl<<"Parenthesis Not matched" << endl;
        }
    }
    system("pause");
    return 0;
  }

The last line is matching, but because it thinks the array size is zero it drops out and states that it doesn't match.

Haven't looked at any of the logic except this:

while(inFile) // the file stream is not yet at eof after the last line has been read
    {
        inFile.getline(inputArray, 8,'\n'); // try to read one past the last line
        // getline fails; and the stream goes an eof state
        // but we proceed as if no error has occurred.
        // ...

The correct idiom to read every line in a stream checks for failure after (not before) attempted input:

    while( inFile.getline(inputArray, 8,'\n') ) // if we have read a line
        {
            // go ahead and do something with the line
            // ...

static const ET CAPACITY = 20; //Size of the array

What happens if you encounter a line that is longer than this?
Is there a compelling reasaon not to use std::string?

Use the standard library - people who say you don't 'learn' C++ by if you use the language library are people who haven't learned C++ yet.
Ignore them for your own good.

Edited 4 Years Ago by vijayan121

I have changed my code, hopefully for the better, but now it's saying that nothing matches. It's showing that nothing matches because the size of the array never appears as zero. I'm sure I'm overlooking something stupid. Any help is greatly appreciated!

class List
{
      public:
        //Typedef declarations
        typedef char Element_Type;//Element Type
        static const Element_Type CAPACITY = 20; //Size of the array

        List()
        {
            //Set to zero
            Position = 0;
            Used = 0;

            //Zero out array
            for(int i = 0; i < CAPACITY; i++)
            {
                MyAry[i] = 0;
            }
        }

         void front()
        {
            //Sets position to the first location
            Position = 0;
        }

        void end()
        {
            //Gets the end position
            if(Used != 0)
            {
                Position = Used - 1;
            }
        }

        void prev()
        {
            //Subtracts one from current position
            if(Position - 1 >= 0)
            {
                Position--;
            }
        }

        bool empty()
        {
            //Used = 0 is returns true
            return Used;
        }

        void next()
        {
            //Adds one to current position
            if(Position + 1 < Used)
            {
                Position++;
            }
        }

        int getPos()
        {
            //Returns current Position
            return Position + 1;
        }


        void setPos(int NewPos)
        {
            //Sets Position to New Position
            if((NewPos >= 0) && (NewPos < Used))
            {
                Position = NewPos;
            }
        }

        bool insertBefore(Element_Type value)
        {
            //Checks for position out of bounds
            if(Position + 1 > CAPACITY)
            {
                return false;
            }
            else
            {
                //If used is zero then first element
                if(Used == 0)
                {
                    MyAry[Used] = value;
                }
                else
                {
                    //Shuffles everything down to make room for new element
                    for(int i = Used; i > Position; i--)
                    {
                        MyAry[i] = MyAry[i - 1];
                    }
                    MyAry[Position] = value;
                }

                Used++;

                return true;
            }
        }

        Element_Type getElement()
        {
            return MyAry[Position];
        }

        bool insertAfter(Element_Type value)
        {
            //Checks for position out of bounds
            if(Position + 1 > CAPACITY)
            {
                return false;
            }
            else
            {
                //If used is zero then first element
                if(Used == 0)
                {
                    MyAry[Used] = value;
                }
                else
                {
                    //Moves everything down to make room for new element
                    for(int i = Used; i > Position + 1; i--)
                    {
                        MyAry[i] = MyAry[i - 1];
                    }
                    MyAry[Position] = value;
                }

                //Increment
                Position++;
                Used++;

                return true;
            }
        }

        int size()
        {
            //Returns size of the array
            return Used;
        }

        void replace(int RepVal)
        {
            //Replace current value at position with new value
            MyAry[Position] = RepVal;
        }

        void clear()
        {
            //Return the List back to zero
            for(int i = 0; i < CAPACITY; i++)
            {
                MyAry[i] = 0;
            }

            //Return values to zero
            Position = 0;
            Used = 0;
        }

        void erase()
        {
            //Move all remaining elements down
            for(int i = Position; i < Used; i++)
            {
                MyAry[i] = MyAry[i + 1];
            }

            //Decrement Used
            Used--;
        }
             friend ostream &operator<<(ostream &stream,List L);

    private:
        Element_Type MyAry[CAPACITY];
        int Used;
        int Position;

};

class Stack
{
    public:
        typedef char Element_Type;//Element Type

        void push(Element_Type value)
        {
            Stack::myStack.end();
            myStack.insertAfter(value);
        }

        void pop()
        {
            myStack.end();
            myStack.erase();
        }

        int size()
        {
            return myStack.size();
        }

        Element_Type top()
        {
            Stack::myStack.end();
            myStack.getElement();

            return myStack.getElement();
        }

        bool empty()
        {
            return myStack.empty();
        }

        void clear()
        {
            myStack.clear();
        }


    private:
        List myStack;
};

ostream &operator<<(ostream &stream,List L)
{
       for(int i=0;i<L.Used;i++)
       {

             stream<<L.MyAry[i]<<" ";
       }
       stream<<endl;
       return stream;
}

//Declare file streams
ifstream inFile;
ofstream outFile;

int main()
  {
    Stack stack1;
    char inputArray[20];
    char value;
    int i=0;

    //Open inFile
    inFile.open("StackStr.txt");

    while(!inFile)
    {
        cout << "Error opening the inFile." << endl;
        return 1;
    }

    //Open outFile
    outFile.open("StackResults.txt");

    while(!outFile)
    {
        cout << "Error opening the outFile." << endl;
        return 1;
    }

    while(inFile)
    {
        for(int j = 0; i < 20; i++)
        {
            inputArray[j] = ' ';
        }
        stack1.clear();

        inFile.getline(inputArray, 20,'\n');
        i = 0;

        while(inputArray[i] != '\0')
        {
            value=inputArray[i];
            cout << value << " ";
            outFile << value << " ";
            i++;

            if(value=='(' || value=='[' || value=='{')
            {
                stack1.push(value);
            }
            else if(value==')' || value==']' || value=='}')
            {
                if(stack1.top() == value)
                {
                    stack1.pop();
                }
            }
        }

        if(stack1.empty() == 0)
        {
            cout<<endl<<"Parenthesis matched" << endl << endl;
            outFile<<endl<<"Parenthesis matched" << endl << endl;
        }
        else
        {
            cout<<endl<<"Parenthesis Not matched" << endl << endl;
            outFile<<endl<<"Parenthesis Not matched" << endl << endl;
        }
    }

    system("pause");
    return 0;
  }
This question has already been answered. Start a new discussion instead.