读取C源文件并跳过/**/comments
我设法在C源代码中编写代码来跳过读取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] != '\
/
注释:
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;}