介绍
c语言风格的注释为块注释,c++风格为行注释。
/*块注释*/
//行注释
在项目中人们喜欢用不同风格的注释,或者两种风格的注释混用,这并不影响代码的功能,但是在一些工具当中要求代码的注释风格统一为c或者c++风格。
所以写了一个处理文件注释的代码。
分析
我们使用了状态机的概念,即在对文件中各个字符检测的时候遇到特定的字符对全局变量赋不同的状态值,来代表代码所处的状态,下面为不同状态间相互转换的示意图。
例如
//Xi/*You*/Linux//Group
首先检测到了”//”这两个字符,进入c++状态,我们将”//”替换为”/* “然后将后面的”/ “,” /”,”//”换成两个空格代替,然后在最后加上”*/”.转换后如下
/*Xi You Linux Group*/
c语言状态下同理。
需要注意的是还有一种状态是引号的状态,在图中并未列出,在” “中的两种注释风格的注释都是无效的,它们被当作字符串处理,所以在” “中的注释的字符原样输出并不进行处理
代码
convertcomment.h
#ifndef _CONVERTCOMMENT_H
#define _CONVERTCOMMENT_H
int convertcomment(FILE *inputfile, FILE *outputfile);
void eventpro(char ch);
void eventpro_no(char ch);
void eventpro_cpp(char ch);
void eventpro_c(char ch);
void eventpro_quo(char ch);
#endif // _CONVERTCOMMENT_H
convert.c
#include <stdio.h>
#include "convertcomment.h"
int main(int argc, char *argv[])
{
FILE *fpin = fopen("./src_file/input.c", "r");
if(NULL == fpin)
{
printf("open input.c fail.\n");
return -1;
}
FILE *fpout = fopen("./dest_file/output.c", "w");
if(NULL == fpout)
{
printf("open output.c fail.\n");
return -1;
}
convertcomment(fpin, fpout);
fclose(fpin);
fclose(fpout);
printf("Commnet Convert Completion.......\n");
return 0;
}
convertcomment.c
#include<stdio.h>
#include "convertcomment.h"
//定义状态
typedef enum
{
no_comment_state,
c_comment_state,
cpp_comment_state,
quo_state,
end_state
}enum_state;
//定义状态机
typedef struct
{
FILE *input;
FILE *output;
enum_state ulstate;
}state_machine;
//定义全局状态机
state_machine g_state;
int convertcomment(FILE *inputfile, FILE *outputfile)
{
if(inputfile==NULL || outputfile==NULL)
{
printf("invalid arugment inputfile or outputfile.\n");
return -1;
}
/////////////////////////////////////////////////////////
//初始化状态机
g_state.input = inputfile;
g_state.output = outputfile;
g_state.ulstate = no_comment_state;
char ch;
while(g_state.ulstate != end_state)
{
ch = fgetc(g_state.input);
eventpro(ch);
}
return 0;
}
void eventpro(char ch)
{
switch(g_state.ulstate)
{
case no_comment_state:
eventpro_no(ch);
break;
case c_comment_state:
eventpro_c(ch);
break;
case cpp_comment_state:
eventpro_cpp(ch);
break;
case quo_state:
eventpro_quo(ch);
break;
}
}
void eventpro_no(char ch)
{
char nextch;
switch(ch)
{
case '/':
nextch = fgetc(g_state.input);
if(nextch == '/') //C++
{
fputc('/', g_state.output);
fputc('*', g_state.output);
g_state.ulstate = cpp_comment_state;
}
else if(nextch=='*')
{
fputc('/', g_state.output);
fputc('*', g_state.output);
g_state.ulstate = c_comment_state;
}
else
{
fputc(ch, g_state.output);
fputc(nextch, g_state.output);
}
break;
case '"':
fputc('"', g_state.output);
g_state.ulstate = quo_state;
break;
case EOF:
g_state.ulstate = end_state;
break;
default:
fputc(ch, g_state.output);
break;
}
}
void eventpro_c(char ch)
{
char nextch;
switch(ch)
{
case '/':
nextch = fgetc(g_state.input);
if(nextch=='/')
{
fputc(' ', g_state.output);
fputc(' ', g_state.output);
}
else
{
fputc(ch, g_state.output);
fputc(nextch, g_state.output);
}
break;
case '*':
nextch = fgetc(g_state.input);
if(nextch=='/')
{
fputc(ch, g_state.output);
fputc(nextch, g_state.output);
g_state.ulstate = no_comment_state;
}
else if(nextch=='*')
{
fseek(g_state.input,-1L,SEEK_CUR); //防止/* ***/这种情况
}
else
{
fputc(ch, g_state.output);
fputc(nextch, g_state.output);
}
break;
case EOF:
g_state.ulstate = end_state;
break;
default:
fputc(ch, g_state.output);
break;
}
}
void eventpro_cpp(char ch)
{
char nextch;
switch(ch)
{
case EOF:
fputc('*', g_state.output);
fputc('/', g_state.output);
g_state.ulstate = end_state;
break;
case '/':
nextch=fgetc(g_state.input);
if(nextch=='/'||nextch=='*')
{
fputc(' ', g_state.output);
fputc(' ', g_state.output);
}
else if(nextch=='\n')
{
fputc(ch, g_state.output);
fputc('*', g_state.output);
fputc('/', g_state.output);
fputc('\n', g_state.output);
g_state.ulstate = no_comment_state;
}
else
{
fputc(ch, g_state.output);
fputc(nextch, g_state.output);
}
break;
case '*':
nextch=fgetc(g_state.input);
if(nextch=='/')
{
fputc(' ', g_state.output);
fputc(' ', g_state.output);
}
else
{
fputc(ch, g_state.output);
fputc(nextch, g_state.output);
}
break;
case '\n':
fputc('*', g_state.output);
fputc('/', g_state.output);
fputc('\n', g_state.output);
g_state.ulstate = no_comment_state;
break;
default:
fputc(ch, g_state.output);
break;
}
}
void eventpro_quo(char ch)
{
char nextch;
switch(ch)
{
case '\n':
case '"':
fputc(ch, g_state.output);
g_state.ulstate = no_comment_state;
break;
case EOF:
g_state.ulstate = end_state;
break;
default:
fputc(ch, g_state.output);
break;
}
}
makefile
cct:convert.o convertcomment.o
gcc -o cct convert.o convertcomment.o
convert.o:convert.c
gcc -o convert.o -c convert.c
convertcomment.o:convertcomment.c
gcc -o convertcomment.o -c convertcomment.c
clean:
rm *.o cct
./src_file/input.c
//每个区由若干个内存块组成
//每个区由若干个内存块组成,//每个块是4096个字节
//int i = 0;*/
//*//*int i = 0;
// /**/int i = 0;
/* int i = 0;
*//*
*/
/* int i = 0;
//*/int j = 0;
/*
//每个区由若干个内存块组成,每个块是4096个字节
//每个块的第0个整数指向下个区
//所以是单链表结构
//所以每个区只有4092个字节存放真正的数据
*/
/* int i = 0;*//*int j = 0;
*/
printf("/*Hello Linux! */");
/*
*//*
*/int i =0;
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 5
//"abcdefghijklmn~~~~!!!!!!!!"
char *str = "hello // world.";
/*abc**/
//char *str = "hello /*123*/ xyz";
./src_file/output.c
/*每个区由若干个内存块组成*/
/*每个区由若干个内存块组成, 每个块是4096个字节*/
/*int i = 0; */
/* int i = 0;*/
/* int i = 0;*/
/* int i = 0;
*//*
*/
/* int i = 0;
*/int j = 0;
/*
每个区由若干个内存块组成,每个块是4096个字节
每个块的第0个整数指向下个区
所以是单链表结构
所以每个区只有4092个字节存放真正的数据
*/
/* int i = 0;*//*int j = 0;
*/
printf("/*Hello Linux! */");
/*
*//*
*/int i =0;
/* 5*/
/*"abcdefghijklmn~~~~!!!!!!!!"*/
char *str = "hello // world.";
/*abc**/
/*char *str = "hello 123 xyz";*/