从C程序中删除注释

时间:2014-07-07 05:12:16

标签: c comments

以下是我从C程序中删除注释的代码。但评论行不会被删除。它会删除/**/,但不会删除此分隔符之间的句子。

#include <stdio.h>

main(int argc, char *argv[]) {
    FILE *fp, *ft;
    char ch;
    if (argc < 3) {
        printf("No file name given");
    }
    fp = fopen(argv[1], "r");
    ft = fopen(argv[2], "w");
    if (fp == NULL)
        printf("Opening error");
    if (ft == NULL)
        printf("Opening error");
    while (1) {
        ch = fgetc(fp);
        if (ch == EOF)
            break;
        if (ch == '/') {
            ch = fgetc(fp);
            if (ch == '*') {
                putc(' ', ft);
            }
        } else if (ch == '*') {
            ch = fgetc(fp);
            if (ch == '/') {
                putc(' ', ft);
            }
        } else {
            putc(ch, ft);
        }
    }
    fclose(fp);
    fclose(ft); 
}

请帮我删除评论专栏。

8 个答案:

答案 0 :(得分:0)

你的最后一部分是写出所有不是 '/' '*' 的字符。 我在下面更改了您的代码。 *******附加行*********显示已更改的部分。试试看并通知我?祝你好运......

#include<stdio.h>

main(int argc,char*argv[])
{

   FILE *fp,*ft;
   char ch;
   int flag=0;   //**********************additional line********

   if(argc<3)
   {
        printf("No file name given");
   }
   fp=fopen(argv[1],"r");
   ft=fopen(argv[2],"w");
   if(fp==NULL)
        printf("Opening error");
   if(ft==NULL)
        printf("Opening error");
   while(1)
   {
        ch=fgetc(fp);
        if(ch==EOF)
                break;
        if(ch=='/')
        {
                ch=fgetc(fp);
                if(ch=='*')
                {
                        flag=1; //**********************additional line********
                        putc(' ',ft);
                }
        }
        else if (ch=='*')
        {
                ch=fgetc(fp);
                if(ch=='/')
                {
                        flag=0;//**********************additional line********
                        putc(' ',ft);
                }
        }
        if(flag==0)   //**********************additional line********
        {
                putc(ch,ft);
        }
   }

   fclose(fp);
   fclose(ft); 


}

答案 1 :(得分:0)

您的代码正确识别了评论开始序列&#34; / &#34;和评论结束序列&#34; /&#34;并删除它们但不删除它们之间的内容(例如标志应该这样做)

/*
 *   flag = 1 if comment detected
 *   flag = 0 otherwise            
 */

if (flag == 0)
  {
    putc (ch, ft);
  }

如果您保持代码原样,它将删除所有&#39; /&#39;不仅在评论中,而且在文件中的任何位置。我可以想到至少有一个不好的结果(调用<sys/time.h><sys/stat.h><netinet/in.h>之类的标题时等等。

由于评论的开始和结束顺序是两个字符宽,我建议您使用2&#34;游标&#34;读取fp,就像每个循环读取2个字符一样。以下是一个例子(尽管它有效,但为了简单和可读性的原因,它不能处理边缘情况,例如EOF之前的非闭合注释,或者在结束注释序列之后的EOF)。

#include <stdio.h>

int
main (int argc, char *argv[])
{
  FILE *fp, *ft;
  char ch, nextc;
  if (argc < 3)
   {
      printf ("No file name given");
   }
  fp = fopen (argv[1], "r");
  ft = fopen (argv[2], "w");
  if (fp == NULL)
    printf ("Opening error");
  if (ft == NULL)
    printf ("Opening error");
  nextc = fgetc (fp);
  while (nextc != EOF)
    {
      ch = nextc;
      nextc = fgetc (fp);

      if ((ch == '/') && (nextc == '*')) 
        {
          nextc = fgetc (fp);
          while ((ch != '*') && (nextc != '/')) /* unroll until the end of comment*/
            {
              ch = nextc;
              nextc = fgetc (fp);
            }
          ch = fgetc (fp);
          nextc = fgetc (fp);
        }

      putc (ch, ft);
    }
  fclose (fp);
  fclose (ft);
  return 0;
}

希望这有帮助。

答案 2 :(得分:0)

只需更改上面代码中的行即可 while((ch!='*')&amp;&amp;(nextc!='/'))

while(!((ch =='*')&amp;&amp;(nextc =='/')))

答案 3 :(得分:0)

对于这个问题,大多数答案只处理多行注释(/..../),但也可能有单行(// ....)行注释。 因此,要处理单行注释,可以在 krouis 的代码中进行轻微修改。

#include <stdio.h>

int main (int argc, char *argv[])
{
  FILE *fp, *ft;
  char ch, nextc;
  if (argc < 3)
  {
       printf ("No file name given");
  }
  fp = fopen (argv[1], "r");
  ft = fopen (argv[2], "w");
  if (fp == NULL)
       printf ("Opening error");
  if (ft == NULL)
       printf ("Opening error");
  nextc = fgetc (fp);
  while (nextc != EOF)
  {
     ch = nextc;
     nextc = fgetc (fp);

     if ((ch == '/') && (nextc == '*')) 
     {
        ch = fgetc (fp);
        nextc = fgetc (fp);
        while (!((ch == '*') && (nextc == '/'))) /* unroll until the end of comment*/
        {
          ch = nextc;
          nextc = fgetc (fp);
        }
        nextc = fgetc (fp);
        continue;
     }else if((ch=='/') && (nextc == '/')) // block to handle single line comment.
     {
        nextc = fgetc (fp);
        while (!(nextc == '\n')){
           nextc = fgetc (fp);
        }
       nextc = fgetc (fp);
       continue;
     }
     putc (ch, ft);
   }
  fclose (fp);
  fclose (ft);
  return 0;
 }

答案 4 :(得分:0)

您还必须处理类似

的内容
printf("Hello World /*a b c*/ ");

因为/ * a b c * /这里实际上不是评论

答案 5 :(得分:0)

您的代码中存在多个问题:

  • main的返回类型不应省略。隐式int已过时,C标准不再允许。原型应为int main(int argc, char *argv[])
  • 如果未将命令行参数传递给程序,则应在输出错误消息后退出,该错误消息应输出到stderr而不是stdout
  • 如果无法打开输入文件,则程序不应创建输出文件。
  • 如果fopen中的任何一个失败,程序应停止运行,而不是进入未定义行为的领域。
  • ch必须具有类型int而非char才能使测试(ch == EOF)正常运行。
  • 您正确地识别了序列/**/并用单个替换了它们,但是实际上它将删除所有其他出现的/和{{1} }和后续字符,您没有任何跳过两者之间字符的规定。
  • *应该返回main

还请注意,如果序列0/*出现在单行注释或字符串或字符常量中,则您的方法可能无法正确识别注释。此外,您还应该处理转义的换行符(位于行尾的*/),因为它们可能出现在\/之间,从而隐藏了注释的开始或结束序列。

这是处理以下情况的修改版本:

*

答案 6 :(得分:0)

您可以尝试以下操作:

- UIWindow
  - backgroundView
  - containerView
    - topContainerView(containers for avatar and nickname)
    - replyView
    - ......

答案 7 :(得分:0)

/* This file is to remove all comments from a c/c++ source file */
/* Modified by John Dai 2020-05-06 */

#include <stdio.h>

int main (void)
{
  char *sourceFile = "D:/Temp/MyCfile.cpp"; //your source code
  char *outputFile = "D:/Temp/MyCfileWoComments.cpp"; //output file

  FILE *fp, *ft;
  char ch, nextc;

  fp = fopen (sourceFile, "r");
  ft = fopen (outputFile, "w");
  if (fp == NULL) {printf ("Error in opening source file\n"); return 1;}
  if (ft == NULL) {printf ("Error in opening output file\n"); return 1;}

  nextc = fgetc (fp);
  while (nextc != EOF)
    {
      ch = nextc;
      nextc = fgetc (fp);


      if ((ch == '/') && (nextc == '/'))
      {
          nextc = fgetc (fp);
          while (nextc != '\n') {// move to the end of line
              nextc = fgetc (fp);
          }
          ch = nextc; //end of line character
          nextc = fgetc(fp); //read 1st character from a new line
      }


      else if ((ch == '/') && (nextc == '*')){
      {
          nextc = fgetc (fp);
          while (!((ch == '*') && (nextc == '/'))) {/* move to the end of comment*/
              ch = nextc;
              nextc = fgetc (fp);
          }
          ch = fgetc (fp); //read first character after the end of comment block
          nextc = fgetc (fp);
        }
      }

      putc (ch, ft);

    }

  fclose (fp);
  fclose (ft);
  return 0;
}