请你编写一个函数,将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——reverse2

    reverse2 附件 例行检查,64位目标 64位ida载入,首先shift+f12检索程序里的字符串 得到了"this is the right flag!" 的提示字符串,还 ...

  2. git 基本命令及idea集成使用

    目录 git基本命令使用 设置签名 gitHub 服务配置秘钥 上传代码 更新代码 分支管理 bat脚本更新 idea集成git git基本命令使用 设置签名 签名和秘钥大多数是一起设置的,设置后一般 ...

  3. HTTP强缓存和协商缓存

    一.浏览器缓存 Web 缓存能够减少延迟与网络阻塞,进而减少显示某个资源所用的时间.借助 HTTP 缓存,Web 站点变得更具有响应性. (一).缓存优点: 减少不必要的数据传输,节省带宽 减少服务器 ...

  4. 可视报表(Project)

    <Project2016 企业项目管理实践>张会斌 董方好 编著 原来一直有一个执念,做项目的人电脑上一定要安装Project软件,今天突然知道了,原来领导的电脑上,可以不装,因为,Pro ...

  5. LuoguP2097 资料分发1 题解

    Content 有一些电脑,一部分电脑有双向数据线连接.如果一个电脑得到数据,它可以传送到的电脑都可以得到数据.现在,你有这个数据,问你至少将其输入几台电脑,才能使所有电脑得到数据. 数据范围:\(n ...

  6. JVM 常见面试题指南

    基础 1. JDK.JRE.JVM的关系是什么? 什么是 JVM? 英文名称 (Java Virtual Machine ),就是JAVA 虛拟机,它只识别 .class 类型文件,它 能够将 cla ...

  7. JAVA获取访问者的内网IP地址

    /** * 获取访问者内网IP * @return the server ip */ public static String getIntranetIp() { // 本地IP,如果没有配置外网IP ...

  8. Android 控件使用教程(一)—— ListView 展示图片

    起因 最近在看一些开源项目时,经常看到了RecyclerView,这是安卓5.0推出的一个新的控件,可以代替传统的ListView,已经这么久了还没有用过,所以决定试一试.另外在做这个的工程中看到了另 ...

  9. 【LeetCode】224. Basic Calculator 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 栈 参考资料 日期 题目地址:https://lee ...

  10. 【LeetCode】23. Merge k Sorted Lists 合并K个升序链表

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:合并,链表,单链表,题解,leetcode, 力扣,Py ...