请你编写一个函数,将C语言源程序中的注释全部删去。

函数原型

// 删除注释
void Pack(FILE *src, FILE *dst);

说明:参数 srcdst 均为文件指针,其中: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);
}
}
}

【PTA】6-1 **删除C程序中的注释 (31 分)的更多相关文章

  1. 怎样批量删除PDF文件中的注释

    日常我们在阅读一些PDF文章时候,我们会发现有些PDF文章带有非常多的注释,显得非常不美观,影响了阅读体验.那么PDF文章里的批注应该怎么进行删除呢?怎样批量删除PDF文件中的注释?   操作教程: ...

  2. IDEA插件:快速删除Java代码中的注释

    背景   有时,我们需要删除Java源代码中的注释.目前有不少方法,比如: 实现状态机.该方式较为通用,适用于多种语言(取决于状态机支持的注释符号). 正则匹配.该方式容易误判,尤其是容易误删字符串. ...

  3. 倍福TwinCAT(贝福Beckhoff)常见问题(FAQ)-如何在程序中添加注释

    在TwinCAT2中,(*中间输入注释*),也可以用这种方法批量注释,在TwinCAT3中,使用//即可     更多教学视频和资料下载,欢迎关注以下信息: 我的优酷空间: http://i.youk ...

  4. 删除C代码中的注释行【状态机】

    今天在学ruby时遇到的一个经典的题目,一直都知道但从来没有实现过.呈上状态机,代码略.(写代码的时候还是需要注意一些小情况的)

  5. LINQ To SQL在N层应用程序中的CUD操作、批量删除、批量更新

    原文:LINQ To SQL在N层应用程序中的CUD操作.批量删除.批量更新 0. 说明 Linq to Sql,以下简称L2S.    以下文中所指的两层和三层结构,分别如下图所示: 准确的说,这里 ...

  6. 在MVC应用程序中,怎样删除上传的文件

    在ASP.NET MVC应用程序中,怎样删除上传的文件. 由于上传时,真正文件是存储在应用程序某一目录,在数据库表中,只是存储其基本信息.在删除时,需要注意一下,由于没有事务可操作.Insus.NET ...

  7. 在DevExpress程序中使用Winform分页控件直接录入数据并保存

    一般情况下,我们都倾向于使用一个组织比较好的独立界面来录入或者展示相关的数据,这样处理比较规范,也方便显示比较复杂的数据.不过在一些情况下,我们也可能需要直接在GridView表格上直接录入或者修改数 ...

  8. [转]MSI安装程序中的文件替换

    原文链接:http://teach.hanzify.org/article/652-1233562028.html 前言 最近有汉化朋友问起如何不重新制作MSI文件,而直接用汉化好的文件替换MSI安装 ...

  9. 程序中保存状态的方式之Cookies

    程序中保存状态的方式之 Cookies,之前写过一篇关于ViewState的.现在继续总结Cookies方式的 新建的测试页面login <%@ Page Language="C#&q ...

随机推荐

  1. [BUUCTF]REVERSE——[FlareOn6]Overlong

    [FlareOn6]Overlong 附件 步骤: 例行检查,32位程序,不懂是个啥 32位ida载入,main函数很简单 处理函数 sub_401000 程序只对unk_402008的28位进行了处 ...

  2. 解决pwn题目加载指定libc版本的问题

    因为本地和远程的libc版本不同,pwn题目调试起来会有影响,所以来记录一下用patchelf和glibc-all-in-one来解决这个问题过程. 下载工具 下载patchelfgit clone ...

  3. Windows异常分发

    当有异常发生时,CPU会通过IDT表找到异常处理函数,即内核中的KiTrapXX系列函数,然后转去执行.但是,KiTrapXX函数通常只是对异常做简单的表征和描述,为了支持调试和软件自己定义的异常处理 ...

  4. 选择…Select…(Power Query 之 M 语言)

    选择行: 筛选Table.SelectRows-文本与数值 筛选Table.SelectRows-日期与时间 保留错误行:= Table.SelectRowsWithErrors( 表, {" ...

  5. Flask与Django的比较

    Flask与Django的区别 Flask Flask确实很"轻",不愧是Micro Framework,从Django转向Flask的开发者一定会如此感慨,除非二者均为深入使用过 ...

  6. UVA10976 分数拆分 Fractions Again?! 题解

    Content 给定正整数 \(k\),找到所有的正整数 \(x \geqslant y\),使得 \(\frac{1}{k}=\frac{1}{x}+\frac{1}{y}\). 数据范围:\(0& ...

  7. CF1130A Be Positive 题解

    Content 有一个长度为 \(n\) 的数组 \(a_1,a_2,a_3,...,a_n\),试找出一个数 \(d\),使得数组中的每个数除以 \(d\) 得到的 \(n\) 个结果中至少有 \( ...

  8. tomcat Address already in use: JVM_Bind

    运行多个tomcat时,出现tomcat Address already in use: JVM_Bind这个错误,可以按照如下方式解决: 修改F:\tomcat20111101\apache-tom ...

  9. PowerDotNet平台化软件架构设计与实现系列(09):消息平台

    消息队列已经几乎成为大中型高吞吐应用的标配,继续根据我们一贯的节约代码的风格,为了复用的目标,抽象出消息队列平台,进行消息队列管理. 环境准备 1.(必须).Net Framework4.5+ 2.( ...

  10. ubuntu(Linux) c++ 获取本机IPv4和ipv6、查询本机IPv4,IPv6

    1.关于 演示环境: Linux xxxxxxx 5.4.0-47-generic #51-Ubuntu SMP Fri Sep 4 19:50:52 UTC 2020 x86_64 x86_64 x ...