由于C和C++的转换风格不同,想将注释风格统一为C++的风格,当代码量过多时,手动转换过于繁多。所以就写一个注释转换小项目来实现将C语言的注释转换为C++的注释风格。下面我们先来画一幅图来整理一下思路:
代码实现时使用了3个文件,两个.c文件和一个.h文件。
//convert.h文件
#ifndef _CONVERT_H
#define _CONVERT_H
enum
{
NULSTA, //普通代码
CSTA, //C注释
CPPSTA, //C++注释
EOFSTA //文件结束
};
void convert();
void do_NULSTA(FILE *ipf,FILE *opf);
void do_CPPSTA(FILE *ipf,FILE *opf);
void do_CSTA(FILE *ipf,FILE *opf);
#define INPUT "input.txt"
#define OUTPUT "output.txt"
#endif
//convert.c文件
#include<stdio.h>
#include"convert.h"
static int status = NULSTA;
void do_NULSTA(FILE *ipf,FILE *opf)
{
int f = fgetc(ipf);
switch(f)
{
case '/': //如果第一个字符是/,判断第二个字符
{
int s = fgetc(ipf);
switch(s)
{
case '/':
fputc('/',opf);
fputc('/',opf);
status = CPPSTA;
break;
case '*':
fputc('/',opf);
fputc('/',opf);
status = CSTA;
break;
case EOF: //如果没有第二个字符,文件结束
status = EOFSTA; //跳转到EOFSTA结束
break;
default:
ungetc(s,ipf); //不是注释字符,就退回去。然后跳到普通文本。
status = NULSTA;
break;
}
}
break;
case EOF: //文件结束
status = EOFSTA;
break;
default:
fputc(f,opf); //不是注释字符,就要输出到目标文件
break;
}
}
void do_CPPSTA(FILE *ipf,FILE *opf)
{
int t = fgetc(ipf);
switch(t)
{
case '\n':
fputc('\n',opf);
status = NULSTA;
break;
case EOF:
status = EOFSTA;
break;
default:
fputc(t,opf);
break;
}
}
void do_CSTA(FILE *ipf,FILE *opf)
{
int n = fgetc(ipf);
switch(n)
{
case '*':
{
int m = fgetc(ipf);
switch(m)
{
case'/':
fputc('\n',opf);
status = NULSTA;
break;
case EOF:
status = EOFSTA;
break;
default:
ungetc(m,ipf);
status = NULSTA;
break;
}
}
break;
case '\n':
fputc('\n',opf);
fputc('/',opf);
fputc('/',opf);
break;
case EOF:
status = EOFSTA;
break;
default:
fputc(n,opf);
break;
}
}
void convert()
{
FILE *ipf=fopen(INPUT,"r");
FILE *opf=fopen(OUTPUT,"w");
if(ipf == NULL || opf == NULL)
{
printf("error\n");
return;
}
while(status != EOFSTA)//如果是EOFSTA则结束循环
{
switch(status)
{
case NULSTA:
do_NULSTA(ipf,opf);
break;
case CPPSTA:
do_CPPSTA(ipf,opf);
break;
case CSTA:
do_CSTA(ipf,opf);
break;
case EOFSTA:
break;
default:
break;
}
}
fclose(ipf);
fclose(opf);
}
//test.c文件
#include<stdio.h>
#include"convert.h"
int main()
{
convert();
return 0;
}
下面是测试用例:
这两个文件都是在这个项目中创建的。
注意:在头文件中加入#IFNDEF....#ENDEF....是为了防止文件被重复声明而试程序崩溃。
注意:在头文件中加入#IFNDEF....#ENDEF....是为了防止文件被重复声明而试程序崩溃。