请你编写一个函数,将C语言源程序中的注释全部删去。
函数原型
// 删除注释
void Pack(FILE *src, FILE *dst);
说明:参数 src
和 dst
均为文件指针,其中:src
指示原始程序文件,dst
指示整理后得到的文件。
C语言规定:注释以 /* 开始,以 / 结束。注释可以跨行,不允许嵌套。字符串中的 / 和 */ 不是注释。
此外C语言还规定:注释相当于一个空白字符。因此,注释被删除后应补入一个空格。
裁判程序
#include <stdio.h>
#include <ctype.h>
#include <string.h>
// 删除注释
void Pack(FILE *src, FILE *dst);
int main()
{
char sname[1024], dname[1024];
FILE *sfile, *dfile;
gets(sname);
gets(dname);
sfile = fopen(sname, "rb");
if (!sfile)
{
printf("%s 无法打开!\n", sfile);
}
dfile = fopen(dname, "wb");
if (!dfile)
{
printf("%s 无法打开!\n", dfile);
}
if (sfile && dfile)
{
printf("正在整理...");
Pack(sfile, dfile);
puts("整理完成!");
}
if (sfile)
{
fclose(sfile);
}
if (dfile)
{
fclose(dfile);
}
return 0;
}
/* 你提交的代码将被嵌在这里 */
思路
在没到文本末尾持续读取
每次开头判断是否读取到EOF,读到则退出
默认初始状态是普通状态
如果是普通状态
- 判断第一个是/,读取下一个,如果是*,改变状态为多行注释,如果是/,改变状态为单行注释,如果是其他,输出这两个字符。
- 判断第一个是单引号,输出单引号,改变状态为字符
- 判断第一个是是双引号,输出双引号,改变状态为字符串
- 判断第一个是其他照常输出
如果是单行注释状态
- 其他字符不输出
- 如果读到换行符,先输出一个空格,再输出换行,然后将状态换为普通状态
如果是多行注释状态
- 其他字符不输出
- 如果读到*号,读取下一个字符,如果是/,输出一个空格,将状态换为普通状态。
如果是字符状态
- 所有字符照常输出
- 如果读到 ’ 号,将状态换为普通状态
如果是字符串状态
- 所有字符照常输出
- 如果读入的是双引号,输出后把状态换为普通状态
- 如果读取到\,则为转义字符,再读取下一个字符一起输出
代码
void Pack(FILE *src, FILE *dst)
{
#define IN_COMMON 1
#define IN_SINGLE 2
#define IN_MULTILINE 3
#define IN_CHARACTER 4
#define IN_STRING 5
int state = IN_COMMON;
int ch1;
int ch2;
while(!feof(src))
{
ch1 = fgetc(src);
if(ch1 == EOF)
break;
if(state == IN_COMMON)//在普通状态
{
if(ch1 == '/')
{
ch2 = fgetc(src);
if(ch2 == '/')//是单行注释
state = IN_SINGLE;
else if(ch2 == '*')//是多行注释
state = IN_MULTILINE;
else
{
fputc(ch1,dst);
fputc(ch2,dst);
}
}
else if(ch1 == '\'')
{
fputc(ch1,dst);
state = IN_CHARACTER;
}
else if(ch1 == '\"')
{
fputc(ch1,dst);
state = IN_STRING;
}
else
fputc(ch1,dst);
}
else if(state == IN_SINGLE)//单行注释状态
{
if(ch1 == '\n')
{
fputc(' ',dst);
fputc(ch1,dst);
state = IN_COMMON;
}
}
else if(state == IN_MULTILINE)//多行注释状态
{
if(ch1 == '*')
{
ch2 = fgetc(src);
if(ch2 == '/')
{
fputc(' ',dst);
state = IN_COMMON;
}
}
}
else if(state == IN_CHARACTER)//字符状态
{
if(ch1 == '\'')
{
fputc(ch1,dst);
state = IN_COMMON;
}
else
fputc(ch1,dst);
}
else if(state == IN_STRING)//字符串状态
{
if(ch1 == '\"')
{
fputc(ch1,dst);
state = IN_COMMON;
}
else if(ch1 == '\\')
{
ch2 = fgetc(src);
fputc(ch1,dst);
fputc(ch2,dst);
}
else
fputc(ch1,dst);
}
}
}