2

I've created a very basic 'debugging' program that checks if a c source file has the same number of opening and closing curly brackets, square brackets and parentheses. I have a code that's fairly simple and it works but the code seems unnecessarily long. I was considering using arrays instead. An array to store each {,[,( and another to store },],) then counting the instance of each and comparing the amounts. But I think that code would be almost as long. What do you guys think?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
FILE *fp;
char fname[20];
char c;
int curlybracket = 0;
int curlybracketr = 0;
int squarebracket = 0;
int squarebracketr = 0;
int parentheses = 0;
int parenthesesr = 0;

printf("Please enter the destination of the file: \n");
scanf("%s", fname);
fp = fopen(fname, "r");

if (fp == NULL)
    {
    printf("Problem opening file!\n");
    exit(0);
    }

else
    {
    printf("File opened correctly\n");
    }

    while (c != EOF)
    {
    c = getc(fp);
        if (c == '{')
            {
            curlybracket++;
            }

        if (c == '[')
            {
            squarebracket++;
            }

        if (c == '(')
            {
            parentheses++;
            }

        if (c == '}')
            {
            curlybracketr++;
            }

        if (c == ']')
            {
            squarebracketr++;
            }

        if (c == ')')
            {
            parenthesesr++;
            }
    }

    if (curlybracket == curlybracketr)
        {
        printf("There are an equal number of curlybrackets\n");
        }
        else
        {
        printf("There is an unequal number of curlybrackets\n");
        return 0;
        }

    if (squarebracket == squarebracketr)
        {
        printf("There are an equal number of squarebrackets\n");
        }
        else
        {
        printf("There are an unequal number of squarebrackets\n");
        }

    if (parentheses == parenthesesr)
        {
        printf("There are an equal number of parentheses\n");
        }
        else
        {
        printf("There are an unequal number of parentheses\n");
        }

return 0;
}
adohertyd
  • 2,689
  • 19
  • 58
  • 78

4 Answers4

3

Your program will report no error if the source file is like "([)]", which is actually illegal.

A better solution is to use a stack, which is a last-in-first-out data structure. This section from the wikipedia page illustrates the usage.

When you read an opening symbol from the file, push it onto the stack. If it's a closing symbol, pop the stack. If the symbol popped is not the corresponding opening symbol, report unbalanced error.

At the end of file, if the stack is empty, the symbols in the file are balanced.

This is the most common way that I know to test whether the symbols are balanced.

lbs
  • 31
  • 1
  • 3
  • Yeah I see what you mean. I haven't worked with stacks before though, I'm fairly new to C. Going to give this a shot anyway. Thanks for the heads up on that. – adohertyd Dec 07 '11 at 12:02
2

Use the switch statement for the list of comparisons with c. If you want your code to be even more concise, use a single array of 256 int values to store the occurrence of each character and compare the array values at { and }.

thiton
  • 35,651
  • 4
  • 70
  • 100
1

True, program can be re-written in more shorter way by using arrays. It could look something like:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
FILE *fp;
char fname[20];
char c;
char brackets[6] = "{}[]()";
int bracketCounts[6] = {0};
char * found;
int i;

printf("Please enter the destination of the file: \n");
scanf("%s", fname);

if ((fp = fopen(fname, "r")) == NULL){
    printf("Problem opening file!\n");
    return 0x00;
}

printf("File opened correctly\n");

// counting various parentheses
while ((c = getc(fp)) != EOF){
    found = strchr(brackets, c);
    if (found != NULL) {
        bracketCounts[found - brackets]++;
    }
}

// dont't forget to close file after reading is done
fclose(fp);

// checking parentheses counters
for (i=0; i < 6; i+=2) {
    if (bracketCounts[i] != bracketCounts[i+1]) {
        printf("Unbalanced parentheses !\n");
        return 0x00;
    }
}

printf("All parentheses are OK!\n");

return 0x00;
}

But it is error-prone as @lbs mentioned, it's far more better to use @lbs approach !

Agnius Vasiliauskas
  • 10,935
  • 5
  • 50
  • 70
0

Count character occurrences in a string

#include <algorithm>
std::string s = "a(b(c))";

int curlybracket = std::count(s.begin(), s.end(), '(') - std::count(s.begin(), s.end(), ')');
if(curlybracket == 0) /* coool */ else /* fail */

Yust another way to solve the problem

Community
  • 1
  • 1
Mhh Lecker
  • 984
  • 1
  • 9
  • 20