-2

I am writing a program in C ..that opens a plain text file containing C-like source code, reads it, and outputs a file with the same content as the first, except that all comments are removed.The program must check that all brackets match,if they do not, the program should display an error message,at showing the type of error and the line number where this error was encountered.(I displayed an error message but how can i locate the error position..?) The input and output files are passed to the program a####nd line parameters, as in: ./your_executable inputfile.txt outputfile.txt

Here is the code that i wrote:

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

/* Functions */
void check_comment (char) ;  // checks for both types of comments, then passes on control to below comments
void block_comment () ;   //  handles block or multiline comments
void single_comment () ;   // handles single line comments

/* 2 file pointers - 1st is for the file in which we check for comments,
and 2nd is the file in which we copy the code after removing comments  */
FILE *fp , *fp2;

int main(void)
{
    char c;

    fp = fopen ("inputfile.txt","r") ;   // open the first file in read mode
    fp2 = fopen ("outputfile.txt","w") ;    // open the second file in write mode
    while((c=fgetc(fp))!=EOF)       // read the file character by character
        check_comment(c);   // check for each character if it seems like the beginning of a comment

     //  close both the files at the end of the program
    fclose(fp);
    fclose(fp2);

    FILE *fp;
    char fname[20];
    char brackets[20] = "{}[]()";
    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 0;
}

// function that handles both types of comments
void check_comment(char c)
{
    char d;

    if( c == '/')   // if the character starts with '/', it 'could' be a comment
    {
        if((d=fgetc(fp))=='*')   // if the next character we read is '*', it is the beginning of multiblock comment
            block_comment();  // pass control to function that handles multiblock comments

        else if( d == '/')   // else if the next character we read is '/', it is the beginning of single line comment
        {
            single_comment();// pass control to function that handles single line comment

        }
        else
        {
            // if both the cases fail, it is not a comment, so we add the character as it is in the new file.
            fputc(c,fp2);
            fputc(d,fp2);
        }
    }

    // again, if all above fails, we add the character as it is in the new file.
    else
        fputc(c,fp2);
}


// function that handles block comments
void block_comment()
{

 char d,e;

    while((d=fgetc(fp))!=EOF)   // the block comment has started, read the character by character
    {
    /* keep reading the characters and do nothing,
    as they do not have to be copied into the new file (we are removing the comments)
    */
        if(d=='*')    // if the comment 'seems' like ending
        {
            e=fgetc(fp);  // check if it actually ends (block comments end with '*/')

            if(e=='/')  // if the comment 'has' ended, return from the function
                return;
        }
   }

}

// function that handles single line comments
void single_comment()
{
 char d,e;

    while((d=fgetc(fp))!=EOF)  // the single line comment has started, read the character by character
    {
    /* keep reading the characters and do nothing,
    as they do not have to be copied into the new file (we are removing the comments)
    */
        if(d=='\n')   // check if the comment ends (single comments end with '\n', or newline)
            return;  // if the comment 'has' ended, return from the function

    }

}

1 Answers1

0

you can implement or use stack data structure, while reading input file if you get { , ( or [ push on the stack and if you get }, ) or ] pop the stack,at the end of input file stack should be empty then you get proper match else some mismatch happened.

along with paranthesis you can keep line numbers(or position, etc)

ex: 1 ( 2 (somethig) 3 something),

push (, line1, then push (, line2 and when you get ) pop (, line2 and so on, in this case if you don't get second closing ), you can say that (, line1 is missing closing.

ShivYaragatti
  • 398
  • 2
  • 8
  • Why if we can just use integer counter and increment or decrement it? – purec Dec 17 '18 at 17:33
  • If we have {{...} How can we determine which one of the first two misses it's half? – purec Dec 17 '18 at 17:40
  • stack is also kind of increment(push) and decrement(pop) only, but along with an array to keep extract information regarding the things at every increment and decrement, that information we can use as per the requirement – ShivYaragatti Dec 17 '18 at 17:43
  • @purec: `{{ ..} ` is the case obiviously closing for first `{ ` is the one missing, if we push like `{1, {2` when we get `}` we pop ` {2` we left one ` {1` – ShivYaragatti Dec 17 '18 at 17:46
  • @ShivYaragatti or for the second ... there is no way to figure out which one is missing the closing one in reality. By convention, the first one is usually picked up for reporting. – Serge Dec 17 '18 at 18:18
  • @Serge: Not sure why you think so, with stack, we can clearly make out what is missing here, consider case 1) `{}{` and 2) `{{}` can't we make out the difference ? in first case clearly close correspong to second open{ is missing and in case 2, close correspinding to first open is missing as it is nested. at the end only mismatch will be left in the stack if we store line number when we push on stack, that's suffice to provide for which open corresponding close is missing . – ShivYaragatti Dec 18 '18 at 03:09
  • @Serge note: for close is missing you can't say where should it close, only we can give line of open `(` for which corresponding close `)` is missing and same way we can also check for open ( missing. – ShivYaragatti Dec 18 '18 at 03:09
  • @ShivYaragatti, we don't know for sure even if we are missing something. – purec Dec 18 '18 at 07:42