以下是简单的将一个文件中的C注释格式改为C++的注释格式的简单逻辑:
注释转换:
先来了解一下C语言与C++注释风格的不同:
C: /* .......*/
C++: //..........
//..........
现在来实现将一份文件中的C注释全部转换为C++注释。
首先要能操作文件的读写:
input.c为原文件,output.c为修改之后的文件,对于两个文件的需求不同,原文件只需要能读到就行,而新文件则需要写入。
不要忘记fclose()。
而input.c中的文件会有以下状态:
状态之间的改变:
首先进入文件是未知状态,获取字符,状态有可能为C++、C、结束、普通字符。
若进入C状态,需要注意以下两点:
1.遇到多/* **** */ 问题,需要用到ungetc解决
ungetc函数是将输出流中的废弃数据退回输入流中去,
将重复的* 退回 input.c中
2.C注释状态之中换行时每行前加上 //
.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
.c
#define _CRT_SECURE_NO_WARNINGS 1
#include "DoCommentConvert.h"
#include <stdio.h>
#include <stdlib.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;
default:
break;
}
}
}
void DoNulState(FILE* pfIn, FILE* pfOut,enum State* ps)
{
int first = 0;
first = fgetc(pfIn);
switch (first)
{
case '/':
{
int second = 0;
second = fgetc(pfIn);
switch (second)
{
case '/':
{
*ps = CPP_STATE;
fputc(first, pfOut);
fputc(second, pfOut);
}
break;
case '*':
{
*ps = C_STATE;
fputc('/', pfOut);
fputc('/', pfOut); //将C注释中的“/*”改为“//”
}
break;
default:
{
fputc(first, pfOut);
fputc(second, pfOut);
}
break;
}
}
break;
case EOF:
{
*ps = END_STATE;
}
break;
default:
{
fputc(first, pfOut);
}
break;
}
}
void DoCState(FILE* pfIn, FILE* pfOut,enum State* ps)
{
int first = 0;
int second = 0;
first = fgetc(pfIn);
switch (first)
{
case '*': //C注释结束的*
{
int second = fgetc(pfIn);
switch (second)
{
case '/':
{
*ps = NUL_STATE;
fputc('\n', pfOut);
}
break;
case '*': //形似/*sfdf***/中的多*问题找到最后一个*
{
fputc(first, pfOut);
ungetc(second, pfIn); //ungetc 必须是输入流而不是输出流
}
break;
default:
{
fputc(first, pfOut);
fputc(second, pfOut);
}
break;
}
}
break;
case '\n': //当在c注释中遇到了换行时,每行加上"//"
{
fputc(first, pfOut);
fputc('/', pfOut);
fputc('/', pfOut);
}
break;
default:
{
fputc(first, pfOut);
}
break;
}
}
void DoCppState(FILE* pfIn, FILE* pfOut,enum State* ps)
{
int first = fgetc(pfIn);
switch (first)
{
case '\n':
{
fputc(first, pfOut);
*ps = NUL_STATE;
}
break;
case EOF:
{
*ps = END_STATE;
}
break;
default:
{
fputc(first, pfOut);
}
break;
}
}
test.c
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "DoCommentConvert.h"
void test()
{
FILE* pfIn = NULL; //输入流,修改前的源文件
FILE* pfOut = NULL; //输出流,修改之后的文件
pfIn = fopen("input.c", "r");
pfOut = fopen("output.c", "w");
if (pfIn == NULL)
{
perror("error opening file");
exit(EXIT_FAILURE);
}
if (pfOut == NULL)
{
perror("error opening file");
fclose(pfIn);
exit(EXIT_FAILURE);
}
DoCommentConvert(pfIn, pfOut);
fclose(pfIn);
fclose(pfOut);
}
int main()
{
test();
printf("转换成功\n");
system("pause");
return 0;
}