C语言小项目-注释转换

来源:互联网 发布:数据结构python版 编辑:程序博客网 时间:2024/05/21 09:18

项目功能

把.c文件中的C风格的注释转换成C++风格的注释
C注释风格: /**/ 可以注释多行
C++注释风格:// 只能注释一行

项目原理

有限状态机转换

实现环境

input.c// 1.一般情况/*int i=0;*/// 2.换行问题/*int i=0;*/int j = 0;/*int i=0;*/int j = 0;// 3.匹配问题/*int i=0;/*xxxxx*/// 4.多行注释问题/*int i=0;int j=0;int k=0;*/int k = 0;// 5.连续注释问题/**//**/// 6.连续的**/问题/***/// 7.C++注释问题// /*xxxxxxxxxxxx*/

在做项目之前,我们需要先分析出可能会出现的几种状态,以及各种状态之间的转换关系
已知这4种状态

  • NUL_STATE:空状态
  • C_STATE:C风格
  • CPP_STATE:C++风格
  • END_STATE:结束状态

    4种状态的转换关系如下图所示

    我们将初始状态置为NUL_STATE状态,通过出现不同的情况分别进入C_STATE状态,CPP_STATE状态和END_STATE状态,下面我们就不同的情况进行具体分析:
    1.在NUL_STATE状态中
    (1)如果出现’/*’则将’//’写入output.c里面并进入C_STATE状态;
    (2)如果出现’//’则直接输出’//’并进入CPP_STATE状态;
    (3)如果出现EOF则进入END_STATE状态。
    2.在C_STATE状态中
    (1)如果出现*/时可能会存在以下几种情况;
    1)*/后面没有任何字符直接忽视掉 */
    2)连续的注释问题/* *// * */
    3)连续的/* **/问题,将读到的字符*写入
    4)/后面出现不出现\n,将\n写入。因为遇到*/说明C注释结束,此时只需要将后面的字符换行。
    (2)如果取出的不是*/而是\n,此时就属于C_STATE的多行注释问题,此时我们需要将\n写入output.c文件中并输出两个/;
    (3)如果出现EOF则进入END_STATE状态;
    (4)如果是其它字符则直接输出。
    3.在CPP_STATE状态中
    (1)如果出现\n,则将\n写入output.c文件中并进入NUL_STATE状态;
    (2)如果出现EOF则进入END_STATE状态;
    (3)如果是其它字符则直接输出。
    程序代码如下所示:

CommentConvert.h#ifndef __COMMENTCONVERT_H__#define __COMMENTCONVERT_H__#include<stdio.h>#define IN_FILENAME "input.c"#define OUT_FILENAME "output.c"typedef enum STATE{    NUL_STATE,    C_STATE,    CPP_STATE,    END_STATE,}STATE;void DoconverWork(FILE *pfin, FILE *pfout);void DoNulState(FILE *pfin, FILE *pfout,STATE *ps);void DoCState(FILE *pfin, FILE *pfout, STATE *ps);void DoCppState(FILE *pfin, FILE *pfout, STATE *ps);#endif //__COMMENTCONVERT_H__CommentConvert.c#include"CommentConvert.h"#include<stdio.h>void DoconverWork(FILE *pfin, FILE *pfout){    STATE state = NUL_STATE;    while (state != END_STATE)    {        switch (state)        {        case NUL_STATE:            DoNulState(pfin, pfout, &state);            break;        case C_STATE:            DoCState(pfin, pfout, &state);            break;        case CPP_STATE:            DoCppState(pfin, pfout, &state);            break;        }    }    fclose(pfin);    fclose(pfout);}void DoCState(FILE *pfin, FILE *pfout, STATE *ps){    int first = 0;    first = fgetc(pfin);    switch (first)    {    case '*':    {                int second = fgetc(pfin);                switch (second)                {                case '/':                {                            int third = fgetc(pfin);                            if (third == '\n')                            {                                fputc(third, pfout);                            }                            else                            {                                ungetc(third, pfin);                                fputc('\n', pfout);                            }                            *ps = NUL_STATE;                }                    break;                case '*':                    fputc(first, pfout);                    ungetc(second, pfin);                    break;                default:                    fputc(first, pfout);                    break;                }    }        break;    case '\n':        fputc(first, pfout);        fputc('/', pfout);        fputc('/', pfout);              break;    case EOF:        fputc(first, pfout);        *ps = END_STATE;//切换结束        break;    default:        fputc(first, pfout);         break;    }}   void DoCppState(FILE *pfin, FILE *pfout, STATE *ps){    int first = 0;    first = fgetc(pfin);    switch (first)    {    case '\n':        fputc(first, pfout);        *ps = NUL_STATE;        break;    case EOF:        fputc(first, pfout);        *ps = END_STATE;//切换结束        break;    default:        fputc(first, pfout);        break;    }}void DoNulState(FILE *pfin, FILE *pfout, STATE *ps){    int first = 0;    first = fgetc(pfin);    switch (first)    {    case '/':    {                int second = fgetc(pfin);                switch (second)                {                case '*':                {                            fputc('/', pfout);                            fputc('/', pfout);                            *ps = C_STATE;                }                    break;                case '/':                {                            fputc(first, pfout);                            fputc(second, pfout);                            *ps = CPP_STATE;                }                    break;                default:                    fputc(first, pfout);                    fputc(second, pfout);                    break;                }    }        break;    case EOF:        fputc(first, pfout);        *ps = END_STATE;//切换结束        break;    default:        fputc(first, pfout);        break;    }}test.c#define _CRT_SECURE_NO_WARNINGS#include"CommentConvert.h"#include<stdlib.h>void test(){    FILE* pfread = NULL;    FILE* pfwrite = NULL;    pfread = fopen(IN_FILENAME, "r");    if (pfread == NULL)    {        perror("open file for read");        exit(EXIT_FAILURE);    }    pfwrite = fopen(OUT_FILENAME, "w");    if (pfwrite == NULL)    {        fclose(pfread);        perror("open file for write");        exit(EXIT_FAILURE);    }    //转换工作    DoconverWork(pfread, pfwrite);    fclose(pfread);    fclose(pfwrite);}int main(){    test();    system("pause");    return 0;}

运行结果

output.c// 1.一般情况//int i=0;// 2.换行问题//int i=0;int j = 0;//int i=0;int j = 0;// 3.匹配问题//int i=0;/*xxxx// 4.多行注释问题////int i=0;//int j=0;//int k=0;//int k = 0;// 5.连续注释问题////// 6.连续的**/问题//*// 7.C++注释问题// /*xxxxxxxxxxxx*/