【问题标题】:Program to read a code and count the number of lines in it,do not include comments and blank lines in count读取代码并计算其中行数的程序,计数中不包括注释和空行
【发布时间】:2010-10-05 04:14:44
【问题描述】:

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

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

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

【问题讨论】:

  • 究竟是如何“不工作”的?
  • 如何修改上面的代码,使空行和注释行不计入?
  • 未初始化ch。您的程序甚至可能永远不会进入 while 循环。
  • 我猜 ch 可以包含任何垃圾而不是 EOF 或者 EOF 也可以被分配为垃圾?
  • 问题 still 代表 “这是我要修复的一大块代码。为我做。” still 不是一个真正的问题。当 OP 准备好说明他没有得到什么时,我们将到达某个地方......直到那时这个应该被关闭。

标签: c whitespace line-count


【解决方案1】:

如果你逐个字符地阅读输入文件,你将比逐行阅读要多得多的工作。毕竟你在数线......

伪代码

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

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

以下版本将忽略带有 // 注释的行,否则为空行。

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

版本 4 将处理多行 cmets。

最重要的是,玩得开心!

【讨论】:

    【解决方案2】:

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

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

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

    此外,您的代码应满足将 cmets 嵌入实际代码行的情况。例如。

    x = 1;    // Set value of x
    

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

    【讨论】:

    • 我应该为 cmets 做什么?任何提示?以及如何处理空行?
    • 我会阅读每一行,去除前导和尾随空格,然后确定字符串是空的、是注释还是真实代码。
    • 忽略它们。一行 C 代码可以包含嵌入的 cmets,也可以在末尾添加 // 注释,但应该算作代码。
    【解决方案3】:

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

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

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

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

    想象这样一条线:

    doSomething(); // foo
    

    【讨论】:

      【解决方案4】:

      除了字符常量的问题之外,您在处理fputc 的方式上也存在错误。 fputc 返回一个 int。如果没有剩余字符变为红色或出现错误,它可以返回 EOF,这是一个负整数常量,或者它可以返回读取为 unsigned char 并转换为 int 的字符的值。

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

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

      形成循环的惯用方式是:

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

      在循环中,您需要小心比较返回值,因为chunsigned char 转换为int 的方式。

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

      例如

      char c = ch;
      
      if (c == '\n')
      

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

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

      【讨论】:

        【解决方案5】:

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

        另一个问题是 C/C++ 中的单行 cmets 实际上以 // 开头,而多行 cmets 以 /* 开头并以 */ 结尾。

        【讨论】:

          猜你喜欢
          • 2017-08-02
          • 2013-05-26
          • 1970-01-01
          • 1970-01-01
          • 2017-03-30
          • 1970-01-01
          • 2017-01-19
          • 2018-04-24
          • 2017-04-10
          相关资源
          最近更新 更多