请你编写一个函数,将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——[WUSTCTF2020]level1

    [WUSTCTF2020]level1 附件 步骤: 下载下来的附件有两个,output.txt里是一堆数字 64位ida打开第一个附件,检索字符串,发现了flag字样 双击跟进,ctrl+x交叉引用 ...

  2. [BUUCTF]PWN——bbys_tu_2016

    bbys_tu_2016 附件 步骤: 例行检查,32位程序,开启了nx保护 本地试运行一下程序,看看大概的情况,测试时候发现输入长度过长程序会崩溃,猜测输入点存在问题 32位ida载入,检索程序里的 ...

  3. SpringMVC 入门、请求、响应

    目录 SpringMVC 概述 SSM 简介 MVC 简介 SpringMVC 简介 入门案例 Spring 技术架构 SpringMVC 基础配置 常规配置 Controller 加载控制 静态资源 ...

  4. Windows10下mysql 8.0.19 安装配置方法图文教程

    第一步 下载安装包: 官网 毕竟是甲骨文公司的产品,去官网下真的慢! 这里有两个供选择的,我建议选第一个(因为我先下了第二个,结果失败了,不知道为什么总是出错.) 下载完自行选择路径解压就可以了. 第 ...

  5. Windows服务(.net Core 3.1-Topshelf-log4net-quartz)

    https://github.com/yezei/Topshelf-log4net-quartz.git

  6. centos7安装docker,并配置镜像加速

    yum安装gcc yum -y install gcc yum -y install gcc-c++ 卸载旧版本 (没有可忽略) yum -y remove docker docker-common ...

  7. JAVA实现返回0001,0002,0003格式数字

    这里只需要修改 %04d 中的4即可设置生成几位数 /** * 获取下一个编号 * @param startValue 上一个编号 * @return */ public static String ...

  8. JAVA整合Redis使用redisTemplate清除库中的所有键值对数据

    JAVA整合Redis使用redisTemplate清除库中的所有键值对数据,清除所有缓存数据 Set<String> keys = redisTemplate.keys("*& ...

  9. 【LeetCode】160. Intersection of Two Linked Lists 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双指针 栈 日期 题目地址:https://leet ...

  10. 【LeetCode】857. Minimum Cost to Hire K Workers 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址: https://leetcode.com/problems/minimum- ...