fin.open("D:\\Advanced Cpp\\Visual Studio\\MatchingGroupSymbols\\Debug\\ProgramA.cpp");
if(fin.fail())
{
cout<<"Program failed to open file."<<endl;
return 0;
}
while(!fin.eof())
{
fin>>ch;
//push left group symbols onto stack
if(ch==LEFTGROUP[0])
stk.push(ch);
elseif(ch==LEFTGROUP[1])
stk.push(ch);
elseif(ch==LEFTGROUP[2])
stk.push(ch);
}
fin.close();
fin.open("D:\\Advanced Cpp\\Visual Studio\\MatchingGroupSymbols\\Debug\\ProgramA.cpp");
while(!fin.eof())
{
fin>>ch;
if(stk.top()==LEFTGROUP[0])
{
if(ch==RIGHTGROUP[0])
stk.pop();
}
elseif(stk.top()==LEFTGROUP[1])
{
if(ch==RIGHTGROUP[1])
stk.pop();
}
elseif(stk.top()==LEFTGROUP[2])
{
if(ch==RIGHTGROUP[2])
stk.pop();
}
}
fin.close();
if(!stk.empty())
cout<<"File has mismatched symbols."<<endl;
elseif(stk.empty())
cout<<"File does not have mismatched symbols."<<endl;
cout << "\n\nProgram complete." << endl;
This is inside a case statement. As you can see, it reads a .cpp file and try to find mismatch symbols. The example below doesn't have any mismatched symbols but it still says that it does. The file is open without problems.
1 2 3 4 5 6 7 8
#include <iostream>
usingnamespace std;
int main()
{
cout << "The result of the expression {[32 * (12 + 5) - 2]} + 17 is "
<< ((32*(12+5)-2)+17) << endl;
return 0;
This is the output when I put the code to print the stack:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Which program you would like to check for pairs of grouping symbols?
1 - ProgramA.cpp
2 - ProgramB.cpp
3 - ProgramC.cpp
Please select an option: 1
File has mismatched symbols.
Program complete.
[
{
{
(
Press any key to continue . . .
Looks like it's finding only the opening symbols...
Yeah, you're pushing the search characters (the left-hand ones) onto a stack, which means you'll be popping them in reverse order. But you're testing the closing characters in original order (when you read the file a second time).
That's not going to work.
Plus, you always look for the matching closing character for the char on the top of the stack. If you happen to come across a different closing char while looking for that specific one, you'll skip it and totally ignore it, leaving it in the stack at the end.
I understand. I'm gonna try creating an array with the left symbols, right symbols, have it run a loop to find those symbols and, if there is an odd number of braces for example, the program will report a mistake. Let me know if anybody has a better idea. Thanks.
You need to be pushing the corresponding RIGHTGROUP char, not ch itself.
Plus the algorithm is missing a pop off the stack for each match found.
You also need to re-order your loop slightly to re-check eof after you've tried reading the next char, not before.
Your line before the while loop helped me figure out a problem that I was having. The number of closing symbols was always greater then what they were supposed to be.
Basically it stores the numbers of opening and closing symbols in two different variables. If the sum of opening and closing symbols is even, then it matches (e.g. 2 opening and two closing parenthesis is a match), but if it is odd (e.g. 2 opening braces and 3 closing braces) then it doesn't match. It is not an awesome approach but it hasn't failed so far. Thanks a lot, guys!
PS: I tried your approach too @jim80y and it works flawesly.
PS2: Now I just need to figure out how to put that in a function because this portion of code will be repeated three times.
If you're doing it that way you'll lose the ability to determine which character is mismatched. If you're never going to want that information, that's OK, but I'd think you may do if you ever extend this program.
Assuming you're going with this method, though, you'd be better of using the string::find() function to determine whether ch is in either of the left/right strings...
1 2 3 4
if (LEFTGROUP.find(ch) != string::npos)
openers++;
elseif (RIGHTGROUP.find(ch) != string::npos)
closers++;
If you don't mind losing the separate counts, even the following will do the job:
1 2 3 4 5 6 7 8 9 10 11 12 13
int difference = 0;
...
while()
{
...
if (LEFTGROUP.find(ch) != string::npos)
difference++;
elseif (RIGHTGROUP.find(ch) != string::npos)
difference--;
}
if (different != 0)
cout << "Mismatch" << endl;