注释转换(C的多行注释 转换为C++的单行注释)

2023-11-07


题目描述

把C的多行注释转换为C++的单行注释

如:把
/*
* int a;
*/
转换为
//
// int a;
//

利用状态转换
在这里插入图片描述


AnnotationConvert.h (状态划分)

分为四个状态

#ifndef __ANNOTATION_CONVERT_H__
#define __ANNOTATION_CONVERT_H__
#include <stdio.h>
#include <stdlib.h>

// C语言风格的注释   /**/
// C++语言风格的注释 //
// 本程序的目标:将C语言风格的注释转换为C++风格的注释
// 待测试数据存在test_in.c文件中 输出结果到test_out.c文件中
#define InputFileName "test_in"
#define OutputFileName "test_out"

enum STATE
{
    NUL_STATE, // 空状态
    C_STATE,   // C语言注释状态
    CPP_STATE, // C++语言注释状态
    END_STATE  // 结束状态
};

void Convert(FILE *fR, FILE *fW);
void Do_NUL_State(FILE *fR, FILE *fW);
void Do_C_State(FILE *fR, FILE *fW);
void Do_Cpp_State(FILE *fR, FILE *fW);

#endif

AnnotationConvert.c (处理每个字符)

具体的状态转换

#include "AnnotationConvert.h"

enum STATE state = NUL_STATE; //初识状态为:NUL 未知态

void Convert(FILE *fR, FILE *fW)
{
    while (state != END_STATE) //扫描到文件尾 跳出循环
    {
        switch (state)
        {
        case NUL_STATE:
            Do_NUL_State(fR, fW);
            break;
        case C_STATE:
            Do_C_State(fR, fW);
            break;
        case CPP_STATE:
            Do_Cpp_State(fR, fW);
            break;
        default:
            break;
        }
    }
}

void Do_NUL_State(FILE *fR, FILE *fW)
{
    int first = 0;
    int second = 0;
    first = fgetc(fR); //fgetc返回字符对应的unsigneint
    switch (first)
    {
    case '/':
        second = fgetc(fR);
        if (second == '*') // 遇到/* 转为C状态
        {
            fputc('/', fW);
            fputc('/', fW);
            state = C_STATE;
        }
        else if (second == '/') // 遇到 // 转为C++状态
        {
            fputc(first, fW);  // '/'
            fputc(second, fW); // '/'
            state = CPP_STATE;
        }
        else //表示 first只是一个简单的'/'字符,输出即可
        {
            fputc(first, fW);
            fputc(second, fW);
        }
        break;

    case EOF: //文件尾
        // fputc(EOF, fW);
        state = END_STATE;
        break;
    default: //状态不变,正常输出
        fputc(first, fW);
        break;
    }
}
void Do_C_State(FILE *fR, FILE *fW) //C状态
{
    int first = 0;
    int second = 0;
    int third = 0;
    first = fgetc(fR);
    switch (first)
    {
    case '*':
        second = fgetc(fR);
        switch (second)
        {
        case '/':
            third = fgetc(fR);
            if (third != '\n') // *等到了/  一次C注释结束了,期待一个换行符'\n'
            {
                fputc('\n', fW);   //若是没有遇到换行符,帮它换行
                ungetc(third, fR); //并将字符放回去,用于下一次的判断
                state = NUL_STATE;
            }
            else
            {
                fputc(third, fW); //若是遇到了换行符,换行即可
                state = NUL_STATE;
            }
            break;
        case '*':
            //second=='*'在等'/'的到来,所以first已经没用了 舍弃first=='*' ,所以不输出first=='*'
            //把second放回去,是因为second=='*'在C状态下,下一个字符可能是'/' ,这样就扫描到来注释尾
            //把second=='*'放回去,是为了检测下一个字符是否是'/'
            ungetc(second, fR);
            break;
        default:
            //'*'没有等到'/' ; 那么舍弃这个first=='*' , 并输出这个second( !='*'  !='/' )(是个普通字符)
            ungetc(second, fR);
            break;
        }
        break;
    case '\n':
        fputc(first, fW); // '\n'
        fputc('/', fW);   //
        fputc('/', fW);   //
        break;
    case EOF:
        // fputc(EOF, fW);
        state = END_STATE;
        break;
    default:
        fputc(first, fW);
        break;
    }
}
void Do_Cpp_State(FILE *fR, FILE *fW)
{
    int first = 0;
    first = fgetc(fR);
    switch (first)
    {
    case '\n':
        fputc(first, fW);
        state = NUL_STATE;
        break;
    case EOF:
        // fputc(EOF, fW);
        state = END_STATE;
        break;
    default:
        fputc(first, fW);
        break;
    }
}

main.c (测试代码)

#include <stdio.h>
#include "AnnotationConvert.h"

int main()
{
    FILE *pR = fopen(InputFileName, "r");
    if (NULL == pR)
    {
        perror("fopen file for read!");
        exit(EXIT_FAILURE);
    }
    FILE *pW = fopen(OutputFileName, "w");
    if (NULL == pW)
    {
        fclose(pR);
        perror("fopen file for write!");
        exit(EXIT_FAILURE);
    }
    printf("Start conversion!\n");
    Convert(pR, pW);
    printf("End of conversion!\n");

    fclose(pR);
    fclose(pW);
    return 0;
}

Makefile (编译)

#------------------目标 ------------------
EXECUTABLE := out	
#------------------文件后缀 ------------------
# .o文件
SrcSuf      = c
ObjSuf      = o
.SUFFIXES: 	.$(SrcSuf) .$(ObjSuf) 
#------------------源文件 ------------------
OBJFILES    +=  ./main.$(ObjSuf) \
				./AnnotationConvert.$(ObjSuf) \

#------------------编译选项 ------------------
# 头文件目录
INCLUDEPATH += 	-I /usr/include/ \
				-I /usr/local/include 
# C编译选项
CFlag += $(INCLUDEPATH) \
		 -w -g -ggdb -fshort-wchar \
		 -std=c11 
#------------------ ------------------
CC          =   gcc

all: $(EXECUTABLE) clean	

#------------------生成可执行文件 ------------------ 			
$(EXECUTABLE):$(OBJFILES)
	@echo "creating $(EXECUTABLE) start..."
	$(CC)  $(OBJFILES) -o $(EXECUTABLE) 
	@echo "creating $(EXECUTABLE) end"
#------------------.c 生成 .o 文件
.$(SrcSuf).$(ObjSuf):
	@echo "Compiling $(EXECUTABLE) $<"
	$(CC) $(CFlag) -c $< -o $@ 
#---------------------------------------------------------
.PHONY:clean
clean:
	rm -f *.o

.PHONY:cleanall
cleanall:
	rm -f $(EXECUTABLE) *.o
#---------------------------------------------------------

test_in (待测试数据)

    // 1.一般情况
    /* int a = 0; */
    int a = 0;

    // 2.换行问题
    /* int b = 0; */int b2 = 0;

    // 3.匹配问题
    /*int c = 0;/*xxxxx*/

    // 4.多行注释问题
    /*
    int d1=0;
    */int d12 = 0;
    /**
    *** int d21 = 0;
    ***
    **/int d22 = 0;

    
    // 5.连续注释问题
    /* *//* */

    // 6.连续的**/问题
    /***/

    // 7.C++注释问题
    // /*xxxxxxxxxxxx*/

test_out (输出)

    // 1.一般情况
    // int a = 0; 
    int a = 0;

    // 2.换行问题
    // int b = 0; 
int b2 = 0;

    // 3.匹配问题
    //int c = 0;/xxxxx

    // 4.多行注释问题
    //
//     int d1=0;
//    
int d12 = 0;
    //
//     int d21 = 0;
//    
//    
int d22 = 0;
    
    // 5.连续注释问题
    // 
// 

    // 6.连续的**/问题
    //

    // 7.C++注释问题
    // /*xxxxxxxxxxxx*/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

注释转换(C的多行注释 转换为C++的单行注释) 的相关文章

  • 【标准解读】Autosar 复杂驱动(CDD)开发--看这一篇就够了

    系列文章目录 提示 写完文章后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 系列文章目录 前言 一 Introduction to CDD 二 CDD设计建议 CDD开发需要注意的事项 2 1 文档 2 2行为和接口描述 2
  • Netty线程模型

    说明 1 Netty抽象出两组线程池 BossGroup专门负责接收客户端的链接 WorkerGroup专门负责网络的读写 2 BossGroup和WorkerGroup类型都是NioEventLooGroup 3 NioEventLoog

随机推荐

  • (转)非常好的WebApi入门文章

    如何在VS中创建基于 NET的后端应用程序 该应用程序使用C 语言从Web API中提取 让我们开始吧 为服务器后端逻辑选择语言的问题是几乎每个开发人员最重要的问题之一 特别是对于初学者 目前已经有很多不同的语言 Java NET C VD
  • 嵌入式数据结构(栈)

    嵌入式自学笔记 1 2 后进先出 3 栈的应用 从A出发进是入栈 红色的出是出栈 4 创建栈的思路 zhan zhancreat int len zhan s if s zhan malloc sizeof zhan NULL printf
  • css选择class中的第一个怎么选?使用first-of-type?

    Dom结构 div span class hha 我是span span h1 class hha 我是h1 h1 h1 我是h1 h1 h1 class hha 我是h1 h1 h1 class hha 我是h1 h1 h1 我是h1 h
  • 如何限制同一客户端登录的用户数量以及禁止同一用户同时在不同客户端登录?

    在web应用系统中 出于安全性考虑 经常需要对同一客户端登录的用户数量和一个客户同时在多个客户端登陆进行限制 具体一点就是 1 在同一台电脑上一次只允许有一个用户登录系统 2 一个用户在同一时间只允许在一个客户端登录 我最近做的一个系统就遇
  • Linux基本命令(二) 文件处理命令

    文件处理命令 touch 命令名称 touch 命令所在路径 bin touch 执行权限 所有用户 语法 touch 文件名 功能描述 创建空文件 范例 touch chen list 文件处理命令 cat 命令名称 cat 命令所在路径
  • UE4 中C++读取Json文件

    本篇文章介绍C 读取Json文件前我们先了解下Json格式 Json格式不同读取会有所区别 踩了一波坑 Json文件有三种格式 这三种格式都是正确的 这边提供一个很有用的Json文件在线编辑平台的网址 在线编辑Json网站 Json文件的三
  • STM32----中断优先级设置

    步骤一 设置中断分组 STM32中断规则 中断优先级分为抢占式优先级和子优先级 对于每一个中断需事先设置其抢占式优先级和子优先级 抢占式优先级级别高的中断可以打断抢占式优先级级别地的中断 抢占式优先级级别相同时 互相均不能打断对方中断执行
  • 计算机专业考研复试上机算法学习

    计算机专业考研复试上机算法学习 这篇博客是博主在准备可能到来的线下上机复试基于王道机试指南的学习 将各道习题链接和代码记录下来 这篇博客权且当个记录 文章目录 计算机专业考研复试上机算法学习 1 STL容器学习 1 1 vector动态数组
  • 网络爬虫之css选择器

    文章目录 通过id class选择元素 元素内部筛选 通过属性值筛选 取值 参考 通过id class选择元素 container 选择id为container的元素 container 选择所有class包含container的元素 di
  • 你不知道的JavaScript-----强制类型转换

    目录 值类型转换 抽象值的操作 JSON 字符串化 ToNumber 非数字值到数字值 Number value ToBoolean 转换为布尔类型 Boolean value 强制类型转换 字符串和数字之间的显式强制类型转换 奇特的 运算
  • Eclipse/MyEclipse闪退之后打不开工作空间的问题解决

    Eclipse MyEclipse闪退之后打不开工作空间的问题解决 在开发过程中偶尔会出现Eclipse MyEclipse闪退之后再启动时打不开工作空间的情况 可以这样解决 1 找到工作空间的目录 例如 E workspace 2 再进入
  • code review

    方法有多种 目前最被认可或运用的方法莫过于CodeReview活动了 那么 CodeReview到底能给团队带来什么 什么样的团队需要进行CodeReview活动 如何有效开展CodeReview活动 用哪种方式会比较好呢 笔者为了接地气地
  • 工业物联网的巨控GRM530无线模块与西门子PLC通信,远程上下载程序

    西门子逆天技术出来了 西门子smart200PLC的数据无线远程传输到上位机 手机APP 概述 随着移动互联网的普及 越来越多的用户希望通过智能手机APP监控工业现场PLC的各种状态 报警等数据 通过手机APP来实现减少人力的投入 还可以实
  • vue中属性key的作用(了解diff),为什么不建议index作为key

    1 官方文档有关key的说明 key 的特殊 attribute 主要用在 Vue 的虚拟 DOM 算法 在新旧 nodes 对比时辨识 VNodes 如果不使用 key Vue 会使用一种最大限度减少动态元素并且尽可能的尝试就地修改 复用
  • 一篇搞定,Kettle详细教程

    文章目录 第一章 Kettle概述 1 1 Kettle发展历程 1 2 Kettle简介 1 3 Kettle相关俗语 1 4 Kettle设计与组成 1 5 Kettle功能模块 1 6 Kettle的执行 Transformation
  • OPT3001光强传感器驱动实现(STM32F407)

    上面是我的微信和QQ群 欢迎新朋友的加入 写了个光强传感器的代码 产品特点 精密光学滤波以匹配人眼 拒绝IR gt 99 典型值 自动满量程设定功能简化了软件 并确保正确的配置 0 01勒克斯至83K勒克斯 23位有效动态范围 自动增益范围
  • 批量汇总nmon结果文件Excel数据

    1 原由 在使用nmon监控服务器资源以后 因为服务器较多 生成了几十个结果文件 现在需要统计每个文件中cpu 内存 disk等平均值 最大值信息 太多表了 就写了个Python脚本 以后可能用的上 先记录一下 nmon生成的Excel中
  • Xml外部实体注入漏洞(XXE)与防护

    Xml外部实体注入 XXE 除了json外 xml也是一种常用的数据传输格式 对xml的解析有以下几种常用的方式 DOM SAX JDOM DOM4J StAX等 然而这几种解析方式都可能会出现外部实体注入漏洞 如微信支付的回调就出现过 见
  • 电脑启机时出\windows\system32\drivers\bootsafe64.sys什么

    开机时出现如下故障解决办法 用老毛桃制作PE启动盘 把C WINDOWS system32 drivers下bootsafe64 sys删除还有一个kavbootc sys删除 重启即可 此问题就出在金山的产品给系统加入的这个文件 它不知出
  • 注释转换(C的多行注释 转换为C++的单行注释)

    目录 题目描述 AnnotationConvert h 状态划分 AnnotationConvert c 处理每个字符 main c 测试代码 Makefile 编译 test in 待测试数据 test out 输出 题目描述 把C的多行