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.
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;
}