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.
精彩评论