Search code examples
cfilecomments

Removing comments in C language


I need to write a program that can remove comments from a file. Removing standard comments is quite simple. However, I haven't been able to come up with a way to remove a "hyphenated" comment. For example, the first two lines of code are comments. My program does not understand this and removes only the first line of the comment.

// Function for output to console\
    ns2

#define _CRT_SECURE_NO_WARNINGS 
#include <stdio.h>
#include <stdlib.h>
#include <iso646.h>

int main() {
    FILE *in = fopen("inp.c", "r");
    FILE *out = fopen("out.c", "w");
    char ch;
    while ((ch = fgetc(in)) not_eq EOF) {
        if (ch == '/') {
            int flag_1 = 0;
            ch = fgetc(in);
            if (ch == '/') {
                flag_1 = 1;
                while ((ch = fgetc(in)) not_eq '\n') {
                    ch = fgetc(in);
                    if (ch == '\\') {
                        ch = '\n'; 
                        break;
                    }
                }
                ch = '\n';
            }
            else if (ch == '*') {
                flag_1 = 1;
                while ((ch = fgetc(in)) not_eq EOF) {
                    if ((ch = fgetc(in)) == '*' and (ch = fgetc(in)) == '/') {
                        ch = '\n';
                        break;
                    }
                }
            }
            if (flag_1 == 0)
                fputc('/', out);
        }
        if (ch == '"') {
            fputc(ch, out);
            while ((ch = fgetc(in)) not_eq '"') {
                fputc(ch, out);
            }
        }
        fputc(ch, out);
    }
    fclose(in);
    fclose(out);
    return 0;
}

I have been trying to supplement / change the program for more than an hour, but the knowledge of a beginner does not allow me to master this task. I will be glad to your advice!


Solution

  • In order to ignore the escaped newlines, sequences of \ followed by a newline, you could use a function that handles this transparently.

    Note also these issues:

    • ch must be defined as an int to handle EOF correctly.
    • the macros defined in <iso646.h> make the code less readable.
    • \ should be handled when parsing strings.
    • character constants should be parsed too: '//' is a valid character constant, not a comment.
    // Function for output to console\
        ns2
    /\
    *\ This is a valid comment too :) 
    *\
    /
    
    #define _CRT_SECURE_NO_WARNINGS 
    #include <stdio.h>
    
    int mygetc(FILE *in) {
        for (;;) {
            int c = getc(in);
            if (c == '\\') {
                c = getc(in);
                if (c == '\n')
                    continue;
                if (c != EOF)
                    ungetc(c, in);
                c = '\\';
            }
            return c;
        }
    }
    
    int skip_line_comment(FILE *in) {
        int c;
        while ((c = mygetc(in)) != '\n' && c != EOF)
            continue;
        return c;
    }
    
    int skip_block_comment(FILE *in) {
        int c;
        for (;;) {
            while ((c = mygetc(in)) != '*') {
                if (c == EOF)
                    return c;
            }
            while ((c = mygetc(in)) == '*')
                continue;
            if (c == EOF)
                return c;
            if (c == '/')
                return ' ';
        }
    }
    
    int main() {
        FILE *in = fopen("inp.c", "r");
        FILE *out = fopen("out.c", "w");
        int ch;
        while ((ch = mygetc(in)) != EOF) {
            if (ch == '/') {
                ch = skip_line_comment(in);
            } else
            if (ch == '*') {
                ch = skip_block_comment(in);
            } else
            if (ch == '"' || ch == '\'') {
                int sep = ch;
                fputc(ch, out);
                while ((ch = mygetc(in)) != sep && ch != EOF) {
                    fputc(ch, out);
                    if (ch == '\\') {
                        ch = mygetc(in);
                        if (ch == EOF)
                            break;
                        fputc(ch, out);
                    }
                }
            }
            if (ch == EOF)
                break;
            fputc(ch, out);
        }
        fclose(in);
        fclose(out);
        return 0;
    }