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


题目描述

把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*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值