C语言小项目-注释转换

项目功能

把.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种状态的转换关系如下图所示
    C语言小项目-注释转换_第1张图片
    我们将初始状态置为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
#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
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

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

你可能感兴趣的:(C语言)