0

I've been following some examples from the K&R book to improve my programming skills. This happens to be example 1-24.

I've written a program that checks a C program for syntax errors like unmatched parentheses, brackets, comments, etc. My problem is that when I run the program, it seems to get stuck in an infinite loop and I'm not entirely sure why. I believe it has to do with 'EOF', which is suppose to get a character until the end of the file is reached.

(c = getchar()) != EOF

The idea is to either increment or decrement a variable depending which character is in the array.

I'm not entirely sure if I'm opening the .c file correctly either. The .c file is located in the same directory as the program to make sure it knows where it's located.

getLine() was written by K&R, but I've written everything else myself.

My code:

/* Includes ------------------------------------------------------------------*/
#include <stdio.h>

/* Typedef -------------------------------------------------------------------*/
/* Define Contant-------------------------------------------------------------*/
#define MAX     1000

/* Macro ---------------------------------------------------------------------*/
/* Global variables ----------------------------------------------------------*/
/* Function prototypes -------------------------------------------------------*/
int getLine(char str[], int lim);
void printErrors(int parentheses, int braces, int brackets, 
                        int singleQ, int doubleQ, int comments);

//Checks for the following:
// () {} [] "" ' ' /* */

int main(void) 
{
    char line[MAX];
    int i, parentheses, braces, brackets, singleQ, doubleQ, comments;
    parentheses = braces = brackets = singleQ = doubleQ = comments = 0;

    //Open the file
    FILE *pFile = fopen("test.c", "r");

    while( getLine(line, MAX) > 0)
    {
        for(i = 0; line[i] != '\0'; ++i)
        {
        //check for syntax balance
            if( line[i] == '(' )
                ++parentheses;
            else if( line[i] == ')' )
                --parentheses;
            else if( line[i] == '{' )
                ++braces;
            else if( line[i] == '}' )
                --braces;
            else if( line[i] == '[' )
                ++brackets;
            else if( line[i] == ']' )
                --brackets;
            else if( line[i] == '\'' )
            {
                if( !singleQ )
                    ++singleQ;
                else
                    --singleQ;
            }
            else if( line[i] == '"' )
            {
                if( !doubleQ )
                    ++doubleQ;
                else
                    --doubleQ;
            }
            else if( (line[i] == '/') && (line[i+1] == '*') )
                ++comments;
            else if( (line[i] == '*') && (line[i+1] == '/') )
                --comments;

        }
    }

    fclose(pFile);

    printErrors(parentheses, braces, brackets, singleQ, doubleQ, comments);

    return 0;
}
void printErrors(int parentheses, int braces, int brackets, 
                        int singleQ, int doubleQ, int comments) 
{
    printf("\n\nPositive interger indicates an extra opening bracket\n");
    printf("\nNegative interger indicates an extra closing bracket\n\n");

    printf("Parenthesis Errors: %d\n", parentheses);
    printf("Brace Errors: %d\n", braces);
    printf("Bracket Errors: %d\n", brackets);
    printf("Single Quote Errors: %d\n", singleQ);
    printf("Double Quote Errors: %d\n", doubleQ);
    printf("Comment Errors: %d\n", comments);
}


int getLine(char str[], int lim)
{

    char c;
    int i = 0;

    while( (i < lim -1) && ((c = getchar()) != EOF) && (c != '\n') ) 
    {
        str[i] = c;
        ++i;
    }

    if( c == '\n' ) 
    {
        str[i] = '\n';
        ++i;
    }
    str[i] = '\0';
    return i;
}

EDIT: I've changed char c to int c, I also used fgetc(), and have moved opening/closing the .c file inside function getLine, but it still has the same behavior. Any other suggestions are greatly appreciated.

int getLine(char str[], int lim)
{

    int c;
    int i = 0;

    //Open the file
    FILE *pFile = fopen("test.c", "r");

    while( (i < lim -1) && ((c = fgetc(pFile)) != EOF) && (c != '\n') ) 
    {
        str[i] = c;
        ++i;
    }

    if( c == '\n' ) 
    {
        str[i] = '\n';
        ++i;
    }
    str[i] = '\0';
    fclose(pFile);

    return i;
}
wait_wut
  • 57
  • 1
  • 8
  • Are you reading from a file or stdin? – Nguai al May 03 '17 at 20:57
  • 4
    You have `char c;` — if plain `char` is an unsigned type, you never get the comparison with EOF true. See: [`while ((c = getc(fp)) != EOF)` won't stop executing](http://stackoverflow.com/questions/13694394/while-c-getcfile-eof-loop-wont-stop-executing/). Use `int c;` — always. However, as @BLUEPIXY points out, your `getLine()` function is reading from standard input, not the file stream you opened. You need to revise the code to pass the file stream to the `getLine()` function and then use it to read characters. Then you might run into the problem I diagnosed. – Jonathan Leffler May 03 '17 at 20:57
  • 1
    You use `fgetc` instead of `getchar` with file pointer `pFile`. – BLUEPIXY May 03 '17 at 20:57
  • I've edited my code and followed what @JonathanLeffler said, but I'm still getting the same behavior. Please check the edit. – wait_wut May 04 '17 at 01:14
  • 1
    Open the file once in the main program as before. Pass the file pointer as a third argument to `getLine()`. Compare with `fgets()`. – Jonathan Leffler May 04 '17 at 01:16
  • @JonathanLeffler that worked perfectly. Thank you. Could you please explain why the file needs to opened in main? – wait_wut May 04 '17 at 01:25
  • 1
    Mainly because by opening and closing the file each time in the function, you keep on rereading the first line of the file. – Jonathan Leffler May 04 '17 at 02:06
  • What should your program do with the following snippet: `f(a[)];` Should it be correctly passed as good? both kinds of parens are balanced, but incorrectly. – Luis Colorado May 05 '17 at 08:07

0 Answers0