I need to write a C++ program. I'm usually pretty decent with C++ but with this one I'm lost. I have to write a program that basically checks to make sure that the braces creating a block in a cpp file are balanced. I'm not looking for anyone to write it for me but I was hoping someone could help me out or point me in the right direction. I've attached the requirements to the post. I don't know how to check for balanced braces and where I REALLY get lost is how to reposition the braces as stated and how to ignore ones not creating a block.

Recommended Answers

All 6 Replies

Create a counter of how many "levels" of braces you are in. What do you mean by reposition? To see if they are part of a block, look at the statement before the opening brace. If it is a for loop, if statement, etc. then it is valid.

Additional to death_oclock, you will need to pass comments and string literals. Since, /* {{ */ and "Some brackets {{{{" and '{' are do not need to be in the counter.

Other than that you need to check that you don't go below zero.
i.e.

int main()
{
//stuff
}}{

Should fail, but a simple counter returns zero.

Finally, you have to be careful of trigraphs. Because ??< //stuff ??> is equivilent to { //stuff } and you could get a mismatch there.

Screw it, I still can't get where to even start. Could someone paste a sample code or something to get me off the ground?

Given all the previous posts, why is this not obvious ??

int counter=0;
open file to read
do
{
    read line
    add/subtract from counter based on { } found.
 } while file.ok

if counter==0 good else bad

Seriously that isn't that difficult ???? If you are good at c++ (which you said) then that is less than 5 minutes work.

Specialization to deal with the stuff in my first post, is another 5 minutes.

Ok, I coded it to check each character as they're read in. It seems to work but now I need to get the output right. The checked code should go out to screen and file but not exactly as it was in the CPP file. In the output file and screen, each brace needs to be on it's own line with an S(for start brace) or E(for end brace) before the brace with a number after each letter to match start and end braces. The braces need to be properly indented to match the code as shown in provided files. For example when checking the attached test.cpp file for braces, your output file should look like the attached output.txt file. My code is below, what modifications should I make?

#include <iostream>
#include <string>
#include <fstream>	
#include <iomanip>
#include <conio.h>

using namespace std;
void openFiles (ifstream&, ofstream&);
void braceCheck (ifstream&, ofstream&);
void checkComments (char&, ifstream&, ofstream&);
void checkString (char&, ifstream&, ofstream&);
void checkChar (char&, ifstream&, ofstream&); 

int main()
{
	ofstream out;
	ifstream in;	

	cout << "This Program verifies matching start \n" 
		<<	"and end braces in a CPP file\n\n";	
	
	openFiles (in, out);	

	braceCheck (in, out);
									
	system("pause");

return 0;
}						
void openFiles (ifstream& inFile, ofstream& out)
{
	string FileName; 
	string outName;
	char tryAgain = 'y';

	while (tolower(tryAgain) == 'y')
	{
		cout << "Please type the name of your input file: ";
		cin >> FileName;	
		cout << endl;	
		
		tryAgain = 'n';

		inFile.open(FileName.c_str());
		if(!inFile)	
		{
			cout << "Can't open input file" << endl <<
			        "Would you like to try again? (y or n): ";
			cin >> tryAgain;
			inFile.clear();
			
			while ((tolower(tryAgain) != 'y')&& (tolower(tryAgain) != 'n'))
			{
				cout << endl << "Please enter y or n! ";
				cin >> tryAgain;
				cout << endl;
			}
		}
	}

	cout << "Enter file name to output to: ";
	cin >> outName;
	cout << endl;

	out.open(outName.c_str());
	
	if(!out)
	{
		cout << "Can't create output file\n";
		getch();
		exit(1);
	}	
}
void braceCheck (ifstream& in, ofstream& out)
{
	int c;
	char character;
	int leftCount = 0;
	int rightCount = 0;
	int totalCount = 0;
	int count = 0;	

	in.get(character);
		while (in && count >= 0)
		{
			while (in && (character == ' ' || character == '\n'))
			{
				cout << character;
				out << character;
				in.get(character);		
			}
			switch (character)
			{
			case '/': checkComments (character, in, out);		
															
				break;
			case '"': checkString (character, in, out);	
														
				break;
			case '\'': checkChar (character, in, out);				
														
				break;
			}
		
			if (character == '{')
			{
				leftCount++;
				count++;		
				totalCount++;

				cout << endl; 
				out << endl;
				
				cout << "S" << leftCount <<  character << "\n";				
				out << "S" << leftCount <<  character << "\n";
			}
			else if (character == '}')
			{
				rightCount++;
				count--;		
				totalCount++;

				cout << endl;
				out << endl;

				cout << "E" << rightCount <<  character << "\n";				
				out << "E" << rightCount <<  character << "\n";
			}	
			else
			{
				cout << character;
				out << character;
			}
			
			if (count < 0)		
			{				
				cout << "\nBraces are out of balance! " << endl << endl;				
				
				cout << "Left's: " << leftCount << endl <<
					    "Right's: " << rightCount << endl << "Total count: "
					 << totalCount << endl << endl;
								}			
			in.get(character);			
		}											
			
						
			if (count == 0)
			{																				
				cout << "\nBraces are in balance! " << endl << endl;				
				
				cout << "Left's: " << leftCount << endl <<
					    "Right's: " << rightCount << endl << "Total count: "
					 << totalCount << endl << endl;		
			}
		
}
void checkComments (char& c, ifstream& in, ofstream& out)
{
	cout << c;
	out << c;
	in.get(c);
	if (c == '/')						
	{
		cout << c;
		out << c;
		while (in && c != '\n')		
		{
			in.get(c);
			cout << c;
			out << c;
		}
	}	
	
	else if (c == '*')				
	{
		cout << c;
		out << c;
		in.get(c);				
		while (in)
		{
			cout << c;
			out << c;
			while (in && c != '*')	
			{
				cout << c;
				out << c;
				in.get(c);
			}							
			if (c == '*')						
			{	
				cout << c;
				out << c;
				in.get(c);
				if (c == '/')
				{
					cout << c;
					out << c;
					return;	
				}
			}						
		}
	}
	else
		return;						
}
void checkString (char& c, ifstream& in, ofstream& out)
{
		do
		{
			cout << c;
			out << c;
			in.get(c);
			while (c == '\"')
			{
				cout << c;
				out << c;
				in.get(c);
			}
			if (c == '\n')
			{
				cout << c;
				out << c;
				return;
			}
			
		}while (in && c != '"');
}
void checkChar (char& c, ifstream& in, ofstream& out)
{				
		do
		{
			cout << c;
			out << c;
			in.get(c);
			while (c == '\'') 
			{
				cout << c;
				out << c;
				in.get(c);
			}
		if ( c == '\n')
		{
			cout << c;
			out << c;
				return;
		}
			
		}while (in && c != '\'');
}

Ok this looks like it nearly works so well done!!

But... it is horrible code.

It is very very difficult to read and hence maintain. Especially, if you got asked to develop it on a bit more.

First consider

(a) what happens if I accidentally enter the same input/output filename ?

(b) in brackcheck how do leftCount/rightCount/count differ?. They can easily be combined as one variable.

(c) Consider this:

int main()
{
   // stuff
   {
      // more stuff
   }
}

I am sure that you don not expect that indented the way your program does. The first } is set as E1 that is wrong?

(d) The double while loop in several functions is completely unnecessary.

(e) The switch statement/if , is a mess, use either a switch or an if / else if / else construction.

(f) what is with the mixing '\n' and endl?? Use one (preferably endl)

(g) Note that you always output character, so do that at the end of the while loop with everything else.

(h) Consider this code:

int main()
{
   /*{*/
//stuff
}

Why do I get /*{{*/ in the output....
The solution to that will solve a lot of other problems....

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.