读取C源文件并跳过/**/comments

读取C源文件并跳过/**/comments,c,comments,C,Comments,我设法在C源代码中编写代码来跳过/注释: while (fgets(string, 10000, fin) != NULL) { unsigned int i; for (i = 0; i < strlen(string); i++) { if ((string[i] == '/') && (string[i + 1] == '/')) { while (string[i += 1] != '\

我设法在C源代码中编写代码来跳过
/
注释:

while (fgets(string, 10000, fin) != NULL)
{
    unsigned int i;
    for (i = 0; i < strlen(string); i++)
    {
        if ((string[i] == '/') && (string[i + 1] == '/'))
        {
            while (string[i += 1] != '\n')
                continue;
        } 
    //rest of the code...
但是它一行一行地读,如果我有

/*

text*/
然后计算文本


如何修复此问题?

即使您假定的工作代码也有几个问题:

  • 它不识别任何上下文,因此它将处理出现在字符串常量或
    /**/注释作为注释的开头
  • 在不太可能的情况下,您碰巧有很长的行,它们将被截断(包括终止的换行符)

  • 最后,C是一种面向流的语言,而不是面向行的语言。应该以这种方式(逐个字符)解析它。为了正确地完成这项工作,您确实需要实现一个更复杂的解析器。如果你正在学习一种新的工具,那么你可以考虑将程序放在Flex词法分析器上。

    即使你假定的工作代码也有几个问题:

  • 它不识别任何上下文,因此它将处理出现在字符串常量或
    /**/注释作为注释的开头
  • 在不太可能的情况下,您碰巧有很长的行,它们将被截断(包括终止的换行符)

  • 最后,C是一种面向流的语言,而不是面向行的语言。应该以这种方式(逐个字符)解析它。为了正确地完成这项工作,您确实需要实现一个更复杂的解析器。如果你正在学习一种新的工具,那么你可以考虑将程序放在Flex词法分析器上。

    即使你假定的工作代码也有几个问题:

  • 它不识别任何上下文,因此它将处理出现在字符串常量或
    /**/注释作为注释的开头
  • 在不太可能的情况下,您碰巧有很长的行,它们将被截断(包括终止的换行符)

  • 最后,C是一种面向流的语言,而不是面向行的语言。应该以这种方式(逐个字符)解析它。为了正确地完成这项工作,您确实需要实现一个更复杂的解析器。如果你正在学习一种新的工具,那么你可以考虑将程序放在Flex词法分析器上。

    即使你假定的工作代码也有几个问题:

  • 它不识别任何上下文,因此它将处理出现在字符串常量或
    /**/注释作为注释的开头
  • 在不太可能的情况下,您碰巧有很长的行,它们将被截断(包括终止的换行符)

  • 最后,C是一种面向流的语言,而不是面向行的语言。应该以这种方式(逐个字符)解析它。为了正确地完成这项工作,您确实需要实现一个更复杂的解析器。如果你正在学习一种新的工具,那么你可以考虑将程序放在Flex词法分析器上。

    < P>此代码可以忽略注释<代码> /**/<代码>(不处理所有的情况,例如在C代码中变量之间的字符串中的写/ *)

    #包括
    #包括
    typedef enum bool//false=0,true=1
    {假,真}布尔;
    int main(int argc,char*argv[])
    {
    FILE*FILE=fopen(“FILE”,“r”);//打开文件
    bool comment=false;
    char str[1001];//每次将包含文件部分的字符串
    如果(文件!=NULL)
    {
    while(fgets(str,sizeof(str),file)!=NULL)
    {
    int i=0;
    
    对于(i=0;i此简单代码可以忽略注释
    /***/
    (不处理所有情况,例如在c代码中变量的引号之间的字符串中写入/*)

    #包括
    #包括
    typedef enum bool//false=0,true=1
    {假,真}布尔;
    int main(int argc,char*argv[])
    {
    FILE*FILE=fopen(“FILE”,“r”);//打开文件
    bool comment=false;
    char str[1001];//每次将包含文件部分的字符串
    如果(文件!=NULL)
    {
    while(fgets(str,sizeof(str),file)!=NULL)
    {
    int i=0;
    
    对于(i=0;i此简单代码可以忽略注释
    /***/
    (不处理所有情况,例如在c代码中变量的引号之间的字符串中写入/*)

    #包括
    #包括
    typedef enum bool//false=0,true=1
    {假,真}布尔;
    int main(int argc,char*argv[])
    {
    FILE*FILE=fopen(“FILE”,“r”);//打开文件
    bool comment=false;
    char str[1001];//每次将包含文件部分的字符串
    如果(文件!=NULL)
    {
    while(fgets(str,sizeof(str),file)!=NULL)
    {
    int i=0;
    
    对于(i=0;i此简单代码可以忽略注释
    /***/
    (不处理所有情况,例如在c代码中变量的引号之间的字符串中写入/*)

    #包括
    #包括
    typedef enum bool//false=0,true=1
    {假,真}布尔;
    int main(int argc,char*argv[])
    {
    FILE*FILE=fopen(“FILE”,“r”);//打开文件
    bool comment=false;
    char str[1001];//每次将包含文件部分的字符串
    如果(文件!=NULL)
    {
    while(fgets(str,sizeof(str),file)!=NULL)
    {
    int i=0;
    对于(i=0;i生成一个int变量。
    如果得到/*,请扫描字符并存储索引。
    继续扫描,直到获得*/。
    如果此时变量!=0,则假定这是结束注释标记,忽略中间的字符。

    生成一个int变量。 如果得到/*,请扫描字符并存储索引。 继续扫描,直到获得*/。 如果此时变量!=0,则假定这是结束注释标记,并忽略该字符
    /*
    
    text*/
    
    #include <stdio.h> 
    #include <string.h> 
    
    typedef enum bool // false = 0 and true = 1
    { false,true}bool;
    int main(int argc, char *argv[])
    {
         FILE* file=fopen("file","r"); // open the file 
         bool comment=false;
         char str[1001]; // string that will contain portion of the file each time     
    
         if (file!=NULL)
         {
             while (fgets(str,sizeof(str),file)!=NULL)
             {
                 int i=0;
                 for (i=0;i<strlen(str);i++)
                 {
                     if (str[i]=='/' && str[i+1] == '*')
                     {
                         comment=true; // comment true we will ignore till the end of comment
                         i++; // skip the * character 
                     }
                     else if (str[i]=='*' && str[i+1] == '/')
                     {
                         comment=false; 
                         i++; // skip the / character
                     }
                     else if (comment==false)
                     {
                         printf("%c",str[i]); // if the character not inside comment print it
                     }
                 }
             }
             fclose(file);
         }
    
         return 0;
    }
    
    /\*([^\*]|\*[^\/])*\*\//
    
    #include <stdio.h>
    
    int main()
    {
        int c, st = 0;
        while ((c = getchar()) != EOF) {
            switch (st) {
            case 0: /* initial state */
                switch (c) {
                case '/': st = 1; break;
                default: putchar(c); break;
                } /* switch */
                break;
            case 1: /* we have read "/" */
                switch (c) {
                case '/': putchar('/'); break;
                case '*': st = 2; break;
                default: putchar('/'); putchar(c); st = 0; break;
                } /* switch */
                break;
            case 2: /* we have read "/*" */
                switch (c) {
                case '*': st = 3; break;
                default: break;
                } /* switch */
                break;
            case 3: /* we have read "/* ... *" */
                switch (c) {
                case '/': st = 0; break;
                case '*': break;
                default: st = 2; break;
                } /* switch */
                break;
            } /* switch */
        } /* while */
    } /* main */
    
    #include <stdio.h>
    
    int main()
    {
        int c, st = 0;
        while ((c = getchar()) != EOF) {
            switch (st) {
            case 0: /* initial state */
                switch (c) {
                case '/': st = 1; break;
                default: putchar(c); break;
                } /* switch */
                break;
            case 1: /* we have read "/" */
                switch (c) {
                case '/': st = 4; break;
                case '*': st = 2; break;
                default: putchar('/'); putchar(c); st = 0; break;
                } /* switch */
                break;
            case 2: /* we have read "/*" */
                switch (c) {
                case '*': st = 3; break;
                default: break;
                } /* switch */
                break;
            case 3: /* we have read "/* ... *" */
                switch (c) {
                case '/': st = 0; break;
                case '*': break;
                default: st = 2; break;
                } /* switch */
                break;
            // in the next line we put // inside an `old' comment
            // to illustrate this special case.  The switch has been put
            // after the comment to show it is not being commented out.
            case 4: /* we have read "// ..." */ switch(c) {
                case '\n': st = 0; putchar('\n'); break;
                } // switch  (to illustrate this kind of comment).
            } /* switch */
        } /* while */
    } /* main */
    
    %option noyywrap
    
    %%
       int i = 0;
    
    \"([^\\"]|\\.)*\"          { i += yyleng ; }       // treatment of strings
    \/\/.*                     {               }       // C++ comments
    \/\*([^*]|\*[^/])*\*\/     {               }       // C  comments
    .|\n                       { i += yyleng ; }       // normal chars
    
    <<EOF>>                    { printf("%d\n",i); return;}
    %%
    
    int main(){ 
      yylex(); 
      return 0;}
    
    $ flex count-non-com.fl
    $ cc -o count-non-com lex.yy.c
    $ count-non-com < input
    
    %option noyywrap 
    %%
    
    \"([^\\"]|\\.)*\"          { ECHO; }       // treatment of strings
    \/\/.*                     {       }       // C++ comments
    \/\*([^*]|\*[^/])*\*\/     {       }       // C  comments
    .|\n                       { ECHO; }       // normal chars
    
    %%
    
    int main(){ 
      yylex(); 
      return 0;}