开发者

Program to read a code and count the number of lines in it,do not include comments and blank lines in count

I am trying to create a program which, given an input file, returns the count of all the lines of code in t开发者_Go百科he 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?


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!


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.


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


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.


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 */.


You can write something like this in Python:

def goodline(l : str) -> int:
    if l.lstrip().startswith("/*") and l.rstrip().endswith("*/"):
        # single line
        return 0
    elif l.lstrip().startswith("/*") and not l.rstrip().endswith("*/"):
        # multi line start
        return 1
    elif not l.lstrip().startswith("/*") and l.rstrip().endswith("*/"):
        # multi line end
        return 2
    elif l.strip() == "":
        # empty line
        return 3
    elif l.lstrip().startswith("//"):
        # single line
        return 0
    else:
        # good line
        return 4

if return from above function is 1, keep iterating on lines until return becomes 2.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜