【C语言】C代码注释转换

C语言注释转换是C语言内比较小的一个课题,这个课题的主要思想是需要考虑到可能出现的情况,然后转换为我们能用程序语言描述的情形。

一般可以分为7种情形:
1.一般情况
/* int i = 0; */

2.换行问题
/* 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 */

在这里每一种情形都可以分步讨论,先判断第一个读取的字符,如果是‘/’ ,就可以考虑是否会出现上面说的情形;如果不是,直接读取然后写入另一个文件中。如果是‘/’,接下来继续判断下一个可能会出现的情况,出现‘*’就跳到C语言转换的函数;如果是‘/’,那么就跳到C++语言转换的函数;如果是其他字符,直接读取然后存入文件中。

//头文件声明部分

#ifndef __COMMENTCONVERT_H__
#define __COMMENTCONVERT_H__
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

enum STATE   //定义4个状态
{
    NUL_STATE,    //无状态,也就是正常状态
    C_STATE,      //C语言状态
    CPP_STATE,    //C++状态
    END_STATE     //文件读取完成
};

void DoConvert(FILE *pfIn,FILE *pfOut);
void DoNULLState(FILE *pfIn,FILE *pfOut,enum STATE *psta);
void DoCState(FILE *pfIn,FILE *pfOut,enum STATE *psta);
void DoCppState(FILE *pfIn,FILE *pfOut,enum STATE *psta);

#endif
//主要函数部分
#include"CommentConvert.h"

void DoConvert(FILE *pfIn,FILE *pfOut)  //判断可能出现的情形
{
    enum STATE state=NUL_STATE;    //开始的时候设置为无状态
    while(state!=END_STATE)        //用while循环控制整个程序的执行
    {
        switch(state)
        {
        case NUL_STATE:
            {
                DoNULLState(pfIn,pfOut,&state);
                break;
            }

        case C_STATE:
            {
                DoCState(pfIn,pfOut,&state);
                break;
            }

        case CPP_STATE:
            {
                DoCppState(pfIn,pfOut,&state);
                break;
            }

        case END_STATE:
            break;

        default:
            break;
        }
    }
}

void DoNULLState(FILE *pfIn,FILE *pfOut,enum STATE *psta) //无状态
{
    char first=0;
    char second=0;
    first=fgetc(pfIn);
    switch(first)         //判断第一个读取的字符是什么
    {
        case '/':
        {
            second=fgetc(pfIn);
            switch(second)
            {
            case '*':      //1.一般情况 
                {
                    fputc('/',pfOut);
                    fputc('/',pfOut);
                    *psta=C_STATE;
                    break;
                }

            case '/':     //7.C++注释问题  

                {
                    fputc(first,pfOut);
                    fputc(second,pfOut); 
                    *psta=CPP_STATE;
                    break;
                }

            default:
                {
                    fputc(first,pfOut);
                    fputc(second,pfOut);
                    break;
                }
            }
            break;
        }

       case EOF:   //文件结束标志
           {
               fputc(first,pfOut);
               *psta=END_STATE;
               break;
           }

       default:    
           {
               fputc(first,pfOut);
               break;
           }
    }
}

void DoCState(FILE *pfIn,FILE *pfOut,enum STATE *psta) //C语言状态
{
    char first=0;
    char second=0;
    char third=0;
    first=fgetc(pfIn);
    switch(first)       //3.匹配问题
    {
    case '*':
        {
            second=fgetc(pfIn);
            switch(second)
            {
            case '/':
                {
                    third=fgetc(pfIn);
                    *psta=NUL_STATE;
                    if(third=='\n')         //2.换行问题
                            fputc('\n',pfOut);

                    else
                    { 
                       fputc('\n',pfOut);
                       ungetc(third,pfIn);
                    }
                    break;
                }

            case '*':      // 6.连续的**/问题  
                {
                    fputc(first,pfOut);
                    ungetc(second,pfIn);
                    break;
                }

            default:
                {
                    fputc(first,pfOut);
                    fputc(second,pfOut);
                    break;
                }
            }
            break;
        }

    case '\n':              //4.多行注释问题
        {
            fputc('\n',pfOut);
            fputc('/',pfOut);
            fputc('/',pfOut);
            *psta=C_STATE;
            break;
        }

    default:
        {
            fputc(first,pfOut);
            break;
        }
    }
}

void DoCppState(FILE *pfIn,FILE *pfOut,enum STATE *psta) //C++状态
{
    char first=0;
    char second=0;
    first=fgetc(pfIn);
    switch(first)
    {
    case '\n':
        {
            fputc(first,pfOut);
            *psta=NUL_STATE;
            break;
        }

     case EOF:
        {
            *state = END_STATE;
            break;
        }       

    default:
        {
             fputc(first,pfOut);
             break;
        }
    }
}
//测试函数
#include<stdio.h>
#include<stdlib.h>
#include"CommentConvert.h"

int main()
{
    FILE *pfIn;
    FILE *pfOut;
    pfIn=fopen("input.c","r");

    if(pfIn==NULL)
    {
        perror("open file failed");
        exit(EXIT_FAILURE);
    }

    pfOut=fopen("output.c","w");

    if(pfOut==NULL)
    {
        fclose(pfIn);
        perror("open  failed\n");
        exit(EXIT_FAILURE);
    }

    DoConvert(pfIn, pfOut);
    fclose(pfIn);
    pfIn=NULL;
    fclose(pfOut);
    pfOut=NULL;
    system("pause");
    return 0;
}

结果如下:
这里写图片描述

总结:
1.本人在写过程中,第一个出现的问题是提示是“open file failed”。反复检查看好几遍,很确定自己建立了这两个文件。最后的最后才发现文件名多了一个字母,满屏的尴尬脸啊!

2.文件正常执行后,发现在换行多行注释的过程中int的i老丢,调试好几次后发现是在写C语言状态的时候没有考虑清楚应该给缓存区放第几个字符。一定要记住在”ungetc(third,pfIn)“中,我们已经判断到第三个字符了,所以放的也是第三个!读取哪个字符就要对哪个字符负责,千万不能“始乱终弃”!

3.有问题一定要去调试!调试!在调试前可以通过对错误现象的分析,初步估计一下问题可能出现在哪里,然后一步一步调试,直到完全找到错误出现的地方。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值