程序读取代码并计算其中的行数,计数中不包括注释和空行

发布于 2024-09-26 06:28:07 字数 843 浏览 2 评论 0原文

我正在尝试创建一个程序,在给定输入文件的情况下,返回输入文件中所有代码行的计数,不包括空白行和注释行。我已经编写了以下代码,但是我需要有关如何排除包含注释和空行的行的帮助。

#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;
}

如何修改上面的代码,使空行和注释行不被计算在内?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

べ映画 2024-10-03 06:28:07

如果逐字符读取输入文件,则比逐行读取输入文件要多得多的工作。毕竟你在计算行数...

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

现在你问...什么是好的行?
对于程序的近似,我建议您考虑一行,除了由 0 个或多个空格组成的行之外的所有内容。此近似值将计算评论,但您可以从这里开发您的程序。

以下版本忽略空行上带有 // 注释的行。

版本 3 可以忽略同时包含 /**/ 的行

,版本 4 将处理多行注释。

最重要的是,玩得开心!

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!

蘑菇王子 2024-10-03 06:28:07

C 注释为 ///* */。以下几行是您的问题所在:

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

另一个问题是,如果没有某种状态机,您无法通过一次读取一个字符来匹配两个字符的注释分隔符。

此外,您的代码应该适应注释嵌入到实际代码行中的情况。例如。

x = 1;    // Set value of x

您最好一次读取文件一行,并检查每一行是否为空白或注释,如果不是则增加计数器。

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.

自我难过 2024-10-03 06:28:07

您的意思是 //、/* 和 */ 而不是 \ * 和 *\

,\ 用作转义字符,这会改变其后面的字符的“含义”。

\n 给你一个换行符。使用 \\ 你会得到一个单一的 \ ,而使用 \' 你会得到一些不会关闭开头的东西 '

如果你用正确的字符替换这些注释字符,你应该得到可以编译的代码。
但它不会正确计数。

想象这样一行:

doSomething(); // foo

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
猥琐帝 2024-10-03 06:28:07

除了字符常量的问题之外,您处理fputc的方式也有错误。 fputc 返回一个 int。如果没有剩余的红色字符或出现错误,它可以返回 EOF(负整数常量),也可以返回作为 unsigned char< 读取的字符的值/code> 并转换为 int

如果在将 fputc 的返回值与 EOF 进行比较之前将其转换为 char,则有效字符可能会等于 EOF< /code> 导致循环提前终止。

另外,while 循环并不是在第一次调用 fputc 之前启动的,因此您在第一次迭代中使用的是 ch 的未初始化值。这可能会导致任何事情发生。

形成循环的惯用方法是:

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

在循环内部,您需要小心比较返回值,因为 chunsigned char code> 转换为 int

在大多数平台上,最简单的做法是创建一个 char 变量以进行比较,尽管您可以将字符常量通过相同的 unsigned charint 转换例程。

例如

char c = ch;

if (c == '\n')

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

其他人指出了您的字符文字的问题。

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.

那片花海 2024-10-03 06:28:07

好吧,问题的一部分是你的 ch 变量只有一个字符长度,但是当你测试注释时,例如 \\\*,这是两个字符长,因此需要使用字符串比较。

另一个问题是,C/C++ 中的单行注释实际上以 // 开头,多行注释以 /* 开头,以 */< 结尾/代码>。

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

深陷 2024-10-03 06:28:07

你可以在 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

如果上面函数的 return 为 1,则继续迭代,直到 return 变为 2。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文