Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C程序中删除注释_C_Comments - Fatal编程技术网

从C程序中删除注释

从C程序中删除注释,c,comments,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 = fope

下面是我从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); 
}
#包括
main(int argc,char*argv[]){
文件*fp,*ft;
char ch;
如果(argc<3){
printf(“未给出文件名”);
}
fp=fopen(argv[1],“r”);
ft=fopen(argv[2],“w”);
如果(fp==NULL)
printf(“打开错误”);
如果(ft==NULL)
printf(“打开错误”);
而(1){
ch=fgetc(fp);
如果(ch==EOF)
打破
如果(ch=='/'){
ch=fgetc(fp);
如果(ch=='*'){
putc('',英尺);
}
}else if(ch=='*'){
ch=fgetc(fp);
如果(ch=='/'){
putc('',英尺);
}
}否则{
putc(ch,ft);
}
}
fclose(fp);
fclose(ft);
}

请帮助我删除注释行。

您的最后一个else部分正在写入所有不是
'/'
'*'的字符。
。 我已经更改了下面的代码*******附加行*******显示更改的零件。试试吧,告诉我??好运气

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


}
#包括
main(int argc,char*argv[])
{
文件*fp,*ft;
char ch;
int flag=0;//**********************附加行********

如果(argc您的代码正确地标识了注释开始序列“/”和注释结束序列“/”,并删除了它们,但没有删除它们之间的内容(例如,一个标志应该这样做)

/*
*如果检测到注释,则标志=1
*否则,标志=0
*/
如果(标志==0)
{
putc(ch,ft);
}
如果代码保持原样,它不仅会删除注释中的所有“/”,还会删除文件中的任何位置。我至少可以想到一个坏结果(当调用诸如
等标题时)

由于注释的开始和结束序列有两个字符宽,我建议您使用两个“游标”来读取fp,就好像每个循环读取两个字符一样(尽管它可以工作,但出于简单性和可读性的原因,它不处理边缘情况,例如EOF之前的非闭合注释,或闭合注释序列之后的EOF)

#包括
int
main(int argc,char*argv[])
{
文件*fp,*ft;
char ch,nextc;
如果(argc<3)
{
printf(“未给出文件名”);
}
fp=fopen(argv[1],“r”);
ft=fopen(argv[2],“w”);
如果(fp==NULL)
printf(“打开错误”);
如果(ft==NULL)
printf(“打开错误”);
nextc=fgetc(fp);
while(nextc!=EOF)
{
ch=nextc;
nextc=fgetc(fp);
如果((ch='/')&&(nextc=='*'))
{
nextc=fgetc(fp);
而((ch!='*')&&(nextc!='/'))/*展开,直到注释结束*/
{
ch=nextc;
nextc=fgetc(fp);
}
ch=fgetc(fp);
nextc=fgetc(fp);
}
putc(ch,ft);
}
fclose(fp);
fclose(ft);
返回0;
}

希望这有帮助。

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


虽然(!((ch='*')和&(nextc=='/'))

对于这个问题,大多数答案只处理多行注释(/../),但也可能有单行注释。 因此,要处理单行注释,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;
 }
#包括
int main(int argc,char*argv[])
{
文件*fp,*ft;
char ch,nextc;
如果(argc<3)
{
printf(“未给出文件名”);
}
fp=fopen(argv[1],“r”);
ft=fopen(argv[2],“w”);
如果(fp==NULL)
printf(“打开错误”);
如果(ft==NULL)
printf(“打开错误”);
nextc=fgetc(fp);
while(nextc!=EOF)
{
ch=nextc;
nextc=fgetc(fp);
如果((ch='/')&&(nextc=='*'))
{
ch=fgetc(fp);
nextc=fgetc(fp);
而(!((ch='*')和&(nextc=='/'))/*展开,直到注释结束*/
{
ch=nextc;
nextc=fgetc(fp);
}
nextc=fgetc(fp);
继续;
}else if((ch='/')&&&(nextc=='/')/)块处理单行注释。
{
nextc=fgetc(fp);
而(!(nextc=='\n')){
nextc=fgetc(fp);
}
nextc=fgetc(fp);
继续;
}
putc(ch,ft);
}
fclose(fp);
fclose(ft);
返回0;
}

您还必须处理以下事项

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

因为/*a b c*/这里实际上不是注释

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

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

/* read the next byte from the C source file, handing escaped newlines */
int getcpp(FILE *fp) {
    int ch;
    while ((ch = getc(fp)) == '\\') {
        if ((ch = getc(fp)) != '\n') {
            ungetc(ch, fp);
            return '\\';
        }
    }
    return ch;
}

/* read and write character and string constants */
int skipstr(int cch, FILE *fp, FILE *ft) {
    int ch;
    putc(cch, ft);
    while ((ch = getcpp(fp)) != EOF) {
        putc(ch, ft);
        if (ch == cch)
            return 0;
        if (ch == '\\') {
            if ((ch = getcpp(fp)) == EOF)
                return EOF;
            putc(ch, ft);
        }
    }
    return EOF;
}

int main(int argc, char *argv[]) {
    FILE *fp, *ft;
    int ch;

    if (argc < 3) {
        fprintf(stderr, "Missing arguments. Need input and output filenames\n");
        return 1;
    }
    if ((fp = fopen(argv[1], "r")) == NULL) {
        fprintf(stderr, "Cannot open input file %s\n", argv[1]);
        return 1;
    }
    if ((ft = fopen(argv[2], "w")) == NULL) {
        fprintf(stderr, "Cannot open output file %s\n", argv[2]);
        return 1;
    }
    while ((ch = getcpp(fp)) != EOF) {
        if (ch == '\'' || ch == '"') {
            if (skipstr(ch, fp, ft)) {
                fprintf(stderr, "unterminated string or character constant\n");
                break;
            }
            continue;
        }
        if (ch == '/') {
            if ((ch = getcpp(fp)) == '*') {
                /* multi-line comment */
                int lastc = 0;
                while ((ch = getcpp(fp)) != EOF) {
                    if (ch == '/' && lastc == '*') {
                        break;
                    }
                    lastc = ch;
                }
                if (ch == EOF) {
                    fprintf(stderr, "unterminated comment\n");
                    break;
                }
                ch = ' ';
            } else if (ch == '/') {
                /* single-line comment */
                while ((ch = getcpp(fp)) != EOF && ch != '\n')
                    continue;
                if (ch == EOF)
                    break;
            } else {
                putc('/', ft);
            }
        }
        putc(ch, ft);
    }
    fclose(fp);
    fclose(ft);
    return 0;
}
#include <stdio.h>
#include <string.h>

#define READ 0
#define SINGLE_LINE_COMMENT 1
#define MULTILINE_COMMENT 2
#define STRING_READ 3
#define CHAR_READ 4
int row = 1;
int col = 0;
int er_line = 0;
int er_col = 0;
void read_source(FILE *src, FILE *dst, int flag, char prev_char, int past_read)
{
    if (feof(src))
    {
        if (flag == STRING_READ)
        {
            printf("Error : non-terminatig string at line :%d col :%d \n", er_line, er_col);
        }
        if (flag == CHAR_READ)
        {
            printf("Error : non-terminatig char constant at line :%d col :%d  \n", er_line, er_col);
        }
        if (flag == MULTILINE_COMMENT)
        {
            printf("Error : comment reach to end of file at line :%d col :%d \n", er_line, er_col);
        }
        fclose(src);
        fclose(dst);
        return;
    }

    char ch = fgetc(src);
    past_read++;
    if (ch == '\n')
    {
        row++;
        col = 0;
    }
    else
    {
        col++;
    }
    char next_ch = '\0';
    switch (ch)
    {
    case '\n':
        if (flag == SINGLE_LINE_COMMENT)
        {
            flag = READ;
            past_read = 0;
        }
        else
        {
            if (flag == STRING_READ)
            {
                printf("Error : non-terminatig string at line :%d col :%d \n", er_line, er_col);
                return;
            }
            if (flag == CHAR_READ)
            {
                printf("Error : non-terminatig char constant at line :%d col :%d  \n", er_line, er_col);
                return;
            }
        }
        break;
    case '/':
        next_ch = fgetc(src);
        if (next_ch == '/')
        {
            if (flag != STRING_READ && flag != CHAR_READ && flag != SINGLE_LINE_COMMENT && flag != MULTILINE_COMMENT)
            {
                flag = SINGLE_LINE_COMMENT;
                er_line = row;
                er_col = col;
                past_read = 0;
            }
        }
        else
        {
            if (next_ch == '*')
            {
                if (flag != STRING_READ && flag != CHAR_READ && flag != SINGLE_LINE_COMMENT && flag != MULTILINE_COMMENT)
                {
                    flag = MULTILINE_COMMENT;
                    er_line = row;
                    er_col = col;
                    past_read = 0;
                }
            }
            else
            {
                fseek(src, -1, SEEK_CUR);
            }
        }
        break;
    case '"':
        if (prev_char != '\\')
        {
            if (flag == STRING_READ)
            {
                flag = READ;
                past_read = 0;
            }
            else
            {
                if (flag != STRING_READ && flag != CHAR_READ && flag != SINGLE_LINE_COMMENT && flag != MULTILINE_COMMENT)
                {
                    flag = STRING_READ;
                    er_line = row;
                    er_col = col;
                    past_read = 0;
                }
            }
        }
        break;
    case '\'':
        if (prev_char != '\\')
        {
            if (flag == CHAR_READ)
            {
                flag = READ;
                past_read = 0;
            }
            else
            {
                if (flag != STRING_READ && flag != CHAR_READ && flag != SINGLE_LINE_COMMENT && flag != MULTILINE_COMMENT)
                {
                    flag = CHAR_READ;
                    er_line = row;
                    er_col = col;
                    past_read = 0;
                }
            }
        }
        else
        {
            if (flag == CHAR_READ)
            {
                if (past_read > 2)
                {
                    flag = READ;
                    past_read = 0;
                }
            }
        }
        break;
    case '*':
        if (flag == MULTILINE_COMMENT)
        {
            next_ch = fgetc(src);
            if (next_ch == '/')
            {
                ch = '\0';
                flag = READ;
                past_read = 0;
            }
            else
            {
                fseek(src, -1, SEEK_CUR);
            }
        }
        break;
    }

    //to work with char constant
    if (flag == CHAR_READ)
    {
        if (ch != '\\')
        {
            if (prev_char != '\\')
            {
                if (past_read > 3)
                {
                    printf(" Error : non-terminatig char constant at line :%d col :%d\n", er_line, er_col);
                    return;
                }
            }
        }
        else
        {
            if (past_read > 3)
            {
                printf(" Error : non-terminatig char constant at line :%d col :%d\n", er_line, er_col);
                return;
            }
        }
    }

    if (flag != MULTILINE_COMMENT && flag != SINGLE_LINE_COMMENT && ch != '\0' && ch != EOF)
    {
        fputc(ch, dst);
    }

    read_source(src, dst, flag, ch, past_read);
    return;
}

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

    FILE *fp = fopen(argv[1], "r");
    FILE *fp2 = NULL;
    if (fp == NULL)
    {
        printf("Unable to open file %s\n", argv[1]);
        return 0;
    }
    fp2 = fopen(argv[2], "w");
    if (fp2 == NULL)
    {
        printf("Unable to open file %s\n", argv[2]);
    }
    read_source(fp, fp2, READ, '\0', 0);
    return 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;
}