注释转换(C转C++)

commentConvert.h
#ifndef _COMMENT_CONVERT_H__
#define _COMMENT_CONVERT_H__

#include<stdio.h>
#include<stdlib.h>

enum State
{
    NUL_STATE,//无注释状态
    C_STATE,//C语言注释状态
    CPP_STATE,//C++注释状态  
    END_STATE//代码结束状态  
};
void DoCommentConvert(FILE* pfIn, FILE* pfOut);
void DoNulState(FILE* pfIn, FILE* pfOut, enum State* ps);
void DoCState(FILE* pfIn, FILE* pfOut, enum State* ps);
void DoCppState(FILE* pfIn, FILE* pfOut, enum State* ps);

#endif //_COMMENT_CONVERT_H__

commentConvert.c
#include "commentConvert.h"

void DoCommentConvert(FILE* pfIn, FILE* pfOut)
{
   enum 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;
      case END_STATE:
          break;

      }

   }

}
//无状态转换
void DoNulState(FILE* pfIn, FILE* pfOut, enum State* ps)
{
    int first = fgetc(pfIn);//从文件中读取一个字符来判断
    switch(first)
    {
    case '/'://表示要进入注释状态
        {
            int second = fgetc(pfIn);//再从文件中读取一个字符来判断  
            switch(second)
            {
            case '*'://表示代码是 /*  表示进入C语言注释状态
                {
                  fputc('/',pfOut);//将它改为C++注释 输出到文件
                  fputc('/',pfOut);
                  *ps = C_STATE;//状态转换为  C注释状态 

                } 
                break;
            case '/'://表示代码是 //  表示进入C++注释状态  
                {
                  fputc(first,pfOut);//将注释输出到文件 
                  fputc(second,pfOut);
                  *ps = CPP_STATE;//状态转换为  C++注释状态 

                }
              break;
            default: //表示这个'/ '是字符   
                {
                 fputc(first,pfOut);//将读取到的字符输出到文件 
                 fputc(second,pfOut);
                }
                break;
            }

        }
        break;
    case EOF://遇到EOF表示代码结束
        {
           *ps = END_STATE;//状态改为 END  
        }
        break;
    default://表示遇到的不是注释  ,状态不变 
        {
           fputc(first,pfOut);//将读取的字符输出到文件  
        }
        break;

    }

}
//c语言状态转换
void DoCState(FILE* pfIn, FILE* pfOut, enum State* ps)
{
   int first = fgetc(pfIn);
   switch(first)
   {
      case '*'://遇到'*'表示C语言注释状态  可能会结束 
         {
             int  second = fgetc(pfIn);
             switch(second)
             {

                case '/'://表示  C语言注释  结束  但要判断之后是不是'\n',因为C++注释是以换行结束的 
                    {
                       int third = fgetc(pfIn);
                       if(third == '\n')//如果是'\n'  
                       {
                         ungetc(third,pfIn);//把回车放回
                       }
                       else
                       {
                          fputc('\n',pfOut);//如果不是 ,我们要帮他换行 
                          ungetc(third,pfIn);//并且要将用来判断的字符 从读取流中的撤销  ,防止下次判断时  少判断一个字符  
                       }
                       *ps = NUL_STATE;//状态装换为无注释状态  
                    }       
                   break;
                default: //如果遇到*,但是后边不是/,把*放进去,*后边的字符放回,比如,/***/,进入c状态以后,  
                         //遇到*,后边的字符也是*,如果把两个*都写进去,后边就只剩下/,就不能找到c状态结束的标志,  
                         //所以,需要把第二个字符原样写回 
                    {
                    fputc(first,pfOut);
                    ungetc(second,pfIn);
                    }
                    break;

             }
         }
       break;
      case '\n'://换行之后要加上 // 因为C++只注释能一行  
          {
             fputc(first,pfOut);
             fputc('/',pfOut);
             fputc('/',pfOut);

          }
          break;
      default://否则直接输出  
          {
               fputc(first,pfOut);
          }
       break;

   }

}
//c++语言状态转换
void DoCppState(FILE* pfIn, FILE* pfOut, enum State* ps)
{
   int ch = fgetc(pfIn);
   switch(ch)
   {
   case '\n':
       fputc(ch,pfOut);//cpp状态,如果遇到回车,cpp状态结束,进入无状态
       *ps = NUL_STATE;
       break;
   case EOF:
       *ps = END_STATE;
       break;
   default:
       fputc(ch,pfOut);
       break;

   }

}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "commentConvert.h"
void test()
{
      FILE* pfIn = NULL;
      FILE* pfOut = NULL;


      pfIn = fopen("input.c","r");
      if(pfIn == NULL)
     {
         perror("open file for read");
         exit(EXIT_FAILURE);
      }
      pfOut = fopen("output.c","w");
      if(pfOut == NULL)
      {
         fclose(pfIn);
         perror("open file for write");
         exit(EXIT_FAILURE);
      }
      //注释转换
      DoCommentConvert(pfIn,pfOut);
      fclose(pfIn);
      pfIn = NULL;
      fclose(pfOut);
      pfOut = NULL;
      printf("转换成功\n");

}
int main()
{
  test();
  return 0;
}

猜你喜欢

转载自blog.csdn.net/dream8834/article/details/80707987