2

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

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

如何修改上面的代码,使空白行和注释行不计入?

4

5 回答 5

3

如果您逐个字符地读取输入文件,则与逐行读取相比,您将做更多的工作。毕竟你在数线......

伪代码

    1.初始化行数为0
    2.读一行
    3.文件结束?是:转到 7
    4. 线路好吗?是:转到 5;否:转到 2
    5.增加行数
    6. 从 2 开始重复
    7.输出行数

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

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

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

版本 4 将处理多行注释。

最重要的是,玩得开心!

于 2010-10-08T16:20:38.237 回答
2

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

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

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

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

x = 1;    // Set value of x

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

于 2010-10-05T04:20:54.437 回答
1

你的意思是 //, /* 和 */ 而不是 \ * 和 *\

\ 用作转义字符,它改变了它后面字符的“含义”。

\n 给你一个换行符。你得到\\一个 \ 和 \' 你得到的东西不会关闭开口 '

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

想象这样一条线:

doSomething(); // foo
于 2010-10-05T04:25:03.677 回答
1

除了字符常量的问题之外,您在处理fputc. fputc返回一个int. EOF如果没有剩余的红色字符或出现错误,它可以返回负整数常量,或者它可以返回读取为 an 并转换为 a 的字符的unsigned charint

如果在比较它之前将它的fputc返回值转换为,那么一个有效字符可能比较等于导致循环过早终止。charEOFEOF

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

形成循环的惯用方式是:

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

在循环中,由于ch转换unsigned charint.

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

例如

char c = ch;

if (c == '\n')

或者

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

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

于 2010-10-08T16:55:08.673 回答
0

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

另一个问题是 C/C++ 中的单行注释实际上以 . 开头//,而多行注释以 . 开头/*和结尾*/

于 2010-10-05T04:19:02.873 回答