views:

151

answers:

5

I am trying to create a program which, given an input file, returns the count of all the lines of code in the input file, excluding blank lines and comment lines. I have written the following code, however I need help with how to exclude lines containing comments and blank lines.

#include<stdio.h>
int main()
{
    int count;
    char ch;
    FILE *fptr;
    clrscr();
    fp=fopen("test.cpp","r");
    if(fp==EOF)
        {
        perror("Error:");
        }
    else
    {
        while(ch!=EOF)
        {
            ch=fgetc(fptr);
            if(ch=='\n')
                count++;
            if(ch=='\\')
                count--;
            if(ch=='\*')
                          {
                while(ch!='*\')
                                    {
                    ch=fgetc(fptr);
                                    }
            }
        }
    printf("the lines in the code are %d\n",count);
    fclose (fptr)
    }
    getchar();
    return 0;
}

How can I modify the above code so that blank lines and comment lines are not counted?

A: 

Well, part of the problem is that your ch variable is only a character in length, but when you test for comments, such as \\ and \*, these are two characters long, and thus need to use string comparison.

Another problem is that one-line comments in C/C++ actually start with //, and multi-line comments start with /* and end with */.

jwir3
+2  A: 

C comments are // and /* */. The following lines are where your problem is:

        if(ch=='\\')
            count--;
        if(ch=='\*')
            while(ch!='*\')
                ch=fgetc(fptr);

The other problem is that you can't match a two-character comment delimiter by reading a character at a time without some sort of state machine.

Also, your code should cater for the case where comments are embedded in real lines of code. eg.

x = 1;    // Set value of x

You'd be far better off reading the file a line at a time, and checking whether or not each line is blank or a comment, and incrementing a counter if not.

Andrew Cooper
what should I do for the comments?Any hint ?and how do I deal with the blank lines?
fahad
I'd be reading each line, stripping leading and trailing white-space, then determining if the string is empty, is a comment, or is real code.
Andrew Cooper
and what if the comments are between the code?
fahad
Ignore them. A line of C code can contain embedded comments, or a // comment at the end, but should be counted as code.
Andrew Cooper
+1  A: 

you mean //, /* and */ instead of \ * and *\

the \ is used as an escape character, which changes the "meaning" of the character after it.

\n gives you a newline. with \\ you get a single \ and with \' you get something that doesn't close the opening '

If you replace those comment-characters with the correct one you should get code that will compile. But it wont count correctly.

Imagine a line like this:

doSomething(); // foo
fluchtpunkt
+1  A: 

If you read the input file character by character, you'll have a lot more work than if you read it line by line. After all you're counting lines ...

psudocode

    1. initialize line count to 0
    2. read a line
    3. end of file? yes: goto 7
    4. is it a good line? yes: goto 5; no: goto 2
    5. increment line count
    6. repeat from 2
    7. output line count

Now you ask ... what is a good line?
For an approximation of the program, I suggest you consider a line everything except lines composed of 0 or more whitespace. This approximation will count comments, but you can develop your program from here.

The following version ignores lines with // coments on an otherwise empty line.

Version 3 could ignore lines containing both /* and */

and version 4 would deal with multi line comments.

Above all, have fun!

pmg
Thanks a lot.Really helped.
fahad
+1  A: 

Apart from your problems with character constants you have errors in the way you deal with fputc. fputc returns an int. It can return either EOF which is a negative integer constant if there were no remaining characters to red or there was an error, or it can return the value of the character read as an unsigned char and converted to a int.

If you convert the return value of fputc to char before comparing it to EOF then a valid character might compare as equal to EOF causing premature termination of your loop.

Also, not that the while loop starts before the first call to fputc so you are using the uninitialized value of ch in the first iteration. This could cause anything to happen.

The idiomatic way to form the loop would be:

int ch;
while ((ch = fgetc()) != EOF)
{
    /* ... */
}

In side the loop you need to be careful in the comparison of the returned value due to the way the fact that ch is the unsigned char converted to an int.

On most platforms the simplest thing to do would be to create a char variable for comparison purposes although you could put your character constants throught the same unsigned char to int conversion routine.

E.g.

char c = ch;

if (c == '\n')

or

if (ch == (unsigned char)'\n')

Others have pointed out the problems with your character literals.

Charles Bailey
Thanks alot.....
fahad