注释转换

主要目的是将C注释转为C++注释

  首先我们应该分几种情况讨论:
  1.若第一个字符是普通字符,则应该直接输出
  2.若第一个字符是/,则应该判断接下来的字符,若为/则是C++注释风格,不用修改;若是*则是C注释风格;若不符合前两个条件则退回到输入文件,检查下一个字符
  3.若知道是C注释风格,则需将其改为C++注释风格,同时在C注释风格中还需判断是否结尾以及结尾后是否还有其他字符,若有其他字符需再次判断

convert.h

#ifndef __COUNTER_H__
#define __COUNTER_H__

enum{
    NULSTAT,     //普通模式
    CSTAT,       //C模式
    CPPSTAT,     //C++模式
    EOFSTAT,     //EOF模式
};

#define INPUT "input.c"
#define OUTPUT "output.c"

void convert_main();

#endif

convert.c

#include <stdio.h>
#include <windows.h>
#include "convert.h"

static int status = NULSTAT;

void do_null_stat(FILE* ipf, FILE* opf)
{
    int c = fgetc(ipf);        //从input.c中读出一个字符
    switch (c)
    {
    case '/':
    {
        int s = fgetc(ipf);    //若第一个字符是/则继续读取第二个字符
        switch (s)
        {
        case '/':             //如果第二个字符是/则为C++模式
            fputc('/', opf);
            fputc('/', opf);
            status = CPPSTAT;
            break;
        case '*':             //如果第二个字符是*则为C模式,需将其风格转为C++注释风格
            fputc('/', opf);
            fputc('/', opf);
            status = CSTAT;
            break;
        default:
            ungetc(s, ipf);   //若不符合前两个条件则退回到输入文件,检查下一个字符
            status = NULSTAT; //继续转为普通模式
            break;
        }
    }
        break;
    case EOF:
        status = EOFSTAT;
        break;
    default:
        fputc(c, opf);  //将字符写入输出文件
        break;
    }

}

void do_cpp_stat(FILE* ipf, FILE* opf)
{
    int c = fgetc(ipf);
    switch (c)
    {
    case '\n':             //遇到换行直接输出到output.c中,之后再次按普通模式检查下一个字符
        fputc(c, opf);
        status = NULSTAT;
        break;
    case EOF:
        status = EOFSTAT;
        break;
    default:               //在遇到前两次情况之前,将从input.c中读取的字符输入到output.c中
        fputc(c, opf); 
        status = CPPSTAT;
        break;
    }
}

void do_c_stat(FILE* ipf, FILE* opf)
{
    int c = fgetc(ipf);
    switch (c)
    {
    case '\n':              //遇到换行直接输出到output.c中,之后输入//做为第二行的注释转换
        fputc('\n', opf);
        fputc('/', opf);
        fputc('/', opf);
        status = CSTAT;
        break;
    case '*':
    {
        int s = fgetc(ipf);     //若遇到*则需检查下个字符
        switch (s)
        {
        case '/':              //若第二个字符为/则还需检查下面字符
        {
            int n = fgetc(ipf);
            if (n == ' ')       //若遇到空格则在第二行中第一个字符不应为空格
            {
                fputc(' ', opf);
                fputc('\n', opf);
            }
            else if (n == '\n')    //若为换行符则直接输出换行
            {
                fputc('\n', opf);
            }
            else                  
            {
                fputc('\n', opf);
                ungetc(n, ipf);    //若不符合前两个条件则退回到输入文件,检查下一个字符
            }
            status = NULSTAT;
            break;
        }
        case EOF:
            status = EOFSTAT;
            break;
        default:
            ungetc(s, ipf);     //若不符合前两个条件则退回到输入文件,检查下一个字符
            status = CSTAT;
            break;
        }
        break;
    }
    case EOF:
        status = EOFSTAT;
        break;
    default:
        fputc(c, opf);         //在遇到前两次情况之前,将从input.c中读取的字符输入到output.c中
        break;
    }
}

static void convert_work(FILE* ipf, FILE* opf)
{
    while (status != EOFSTAT)
    {
        switch (status)
        {
        case NULSTAT:
            do_null_stat(ipf, opf);    //执行普通模式
            break;
        case CPPSTAT:
            do_cpp_stat(ipf, opf);     //执行C++模式
            break;
        case CSTAT:
            do_c_stat(ipf, opf);       //执行C模式
            break;
        case EOFSTAT:
            break;
        default:
            break;
        }
    }
}

void convert_main()
{
    FILE* ipf = fopen(INPUT, "r");
    FILE* opf = fopen(OUTPUT, "w");
    if (ipf == NULL || opf == NULL)
    {
        fprintf(stderr, "open file erro\n");
        exit(1);
    }
    convert_work(ipf, opf);
    fclose(ipf);
    fclose(opf);
}

test.c

#include "convert.h"

int main()
{
    convert_main();
    system("pause");
}

结果如图所示

结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值