下面的程序实现了两个功能:
1.读入一个.c源文件,对其中的大括号进行处理,使其独占一行;
2.处理后的文件单独保存并加行号输出;
考察文件中两个字符(这里是指除了回车、制表符以外的字符)的相对位置关系的各种情况,分别进行处理,可以实现大括号独占一行的目的。值得注意的是,对已独占一行的括号不会产生多余的输出(回车)。
大括号前后字符对照表
其实,虽然case有七种情况,但是输出只有两种:需要加回车、不需要加。括号-括号的情形显然可以归结到括号-ASCII码中,即六种情况,只有flag等于1时需要加回车输出。
#include
#include
FILE *braket_deal(FILE *fp_in);
void main(){
int i=1;
FILE *fp_in,*fp_put;
char ch;
fp_in=fopen("file.c","r");
fp_put=braket_deal(fp_in);
fclose(fp_in);
printf("处理后的程序如下\n");
//在每行字符之前加入一个行号
printf("%d",i);
while(!feof(fp_put))
{
ch=fgetc(fp_put);
if(ch=='\n')
{
i++;
printf("%c%-3d",ch,i);
/* ch=fgetc(fp_put); 若换成这条语句,当遇到连续多个回车又没有下面的else时,第二个回车会在没有输出行号
的情况下直接输出*/
}
else
putchar(ch);
}
fclose(fp_put);
}
//对源文件中的大括号进行检测并使其独占一行,返回处理后的文件的指针,返回类型是FILE
FILE *braket_deal(FILE *fp_goal)
{
FILE *fp_deal;
//方式1 char ch,temp[4]={'\n',' ','\n'};
char ch[2],now;
int flag;
fp_deal=fopen("Change_file.c","w+");
if(fp_goal==NULL) {
printf("原文件打开失败\n");
exit(1);
}
else if(fp_deal==NULL) {
printf("文件处理失败\n");
exit(1);
}
/*方式1 while(!feof(fp_goal)) { //方式1这种处理只考虑了"a{c"这种情况,如果大括号已经占了一行,则会多占一行
//但是其代码明显简洁得多,最多多输出两个回车而已
ch=fgetc(fp_goal);
if((ch=='{'||ch=='}') {
temp[1]=ch;
fputs(temp,fp_deal);
}
else
fputc(ch,fp_deal);
}
*/
ch[0]='\0'; //方式2考虑所有的情况,但是代码复杂度较高
while(!feof(fp_goal))
{
ch[1]=fgetc(fp_goal);
if(ch[1]==' '||ch[1]=='\t') flag=0;
else
{
if(ch[0]=='{'||ch[0]=='}')
if(ch[1]=='\n') flag=0; //括号-回车
else flag=1; //括号-字符
else if(ch[0]=='\n') flag=0; //回车-括号
else if(ch[1]=='{'||ch[1]=='}') flag=1; //字符-括号
else flag=0; //字符-字符
ch[0]=ch[1];
}
if(flag==1) fprintf(fp_deal,"\n%c",ch[1]);
else
fputc(ch[1],fp_deal);
}
rewind(fp_deal); //等价于fseek(fp_deal,0,0);
//由于文件位置指针当前指向文件末尾,手动给其复位,为后面主函数中使用提供方便
printf("程序处理完毕!\n");
return fp_deal;
}
对大括号进行分别处理的程序流程图如下: