/*
*在进行软件开发时,为自己编写几款有用的工具软件,会帮助自己更加容易和高效的完成工作
*这里是一款将源程序中的字符串分离出来,并使用宏代替的软件工具,你可以看到,它是如此简单,
*以至于任何一个程序员都可以轻易做到,但我不敢想象,如果没有它,
*用手工完成相同的工作将浪费我多少宝贵的时间
*/
//检测字符串,将字符串用宏替代,并书写宏文件,并将宏文件加入文件头
//宏格式STR_$FILENAME_$LINE_$NUM
#include "stdio.h"
#include "assert.h"
#include "windows.h"
//对输入文件进行过滤
int strext(char *filename,char *headname)
{
FILE *fpin,*fpout,*fphead;
int num=0;
char outfilename[20];
char ch;
int line=2;//第一行加入头文件引用
//输入文件
if(!filename||!(fpin=fopen(filename,"r")))
{
printf("输入文件%s未能打开。\n",filename);
return 1;
}
sprintf(outfilename,"%s.tmp",filename);
//输出文件
if(!(fpout=fopen(outfilename,"w")))
{
printf("输出文件%s不能打开\n",outfilename);
fclose(fpin);
return 1;
}
//输出头文件
if(!headname||!(fphead=fopen(headname,"a")))
{
fphead=stdout;
printf("/*输出头文件不存在,使用显示器代替。*/\n");
}
//加入头文件
if(headname)
fprintf(fpout,"#include \"%s\"\n",headname);
//开始过滤
fprintf(fphead,"/*%s*/\n",filename);
while((ch=fgetc(fpin))&&ch!=EOF)
{
while(ch=='\n')//消除空行
{
fputc(ch,fpout);//输出回车符
line++; //行++
ch=fgetc(fpin); //读取下一行首
if(ch=='#')//行首为#,此为宏
{
fputc(ch,fpout);//输出#
while((ch=fgetc(fpin))&&(ch!=EOF)&&(ch!='\n'))
fputc(ch,fpout);//跳过该行//输出该行内容
if(ch==EOF)
return 0;
}
}
if(ch=='\\')////// //跳过转意字符
{
fputc('\\',fpout);
ch=fgetc(fpin);
fputc(ch,fpout);
}
else if(ch=='\"')//字符串开始
{
char *p=strchr(filename,'.');
if(p)
*p='\0';
fprintf(fpout,"STR_FILE%s_LINE%d_NUM%d",filename,line,++num);
fprintf(fphead,"#define STR_FILE%s_LINE%d_NUM%d\t\"",filename,line,num);
if(p)
*p='.';
p=NULL;
while((ch=fgetc(fpin))&&ch!=EOF)
{
if(ch=='\n')
{
fputc('\\',fphead);
fputc('n',fphead);
}
else if(ch=='\\')
{
fputc('\\',fphead);
ch=fgetc(fpin);
fputc(ch,fphead);
}
else if(ch=='\"')//字符串结束
{
fputc('\"',fphead);//分号
fputc('\n',fphead);//断行
break;
}
else
fputc(ch,fphead);
}
}
else
fputc(ch,fpout);
}
fclose(fpin);
fclose(fpout);
if(fphead!=stdout)
fclose(fphead);
remove(filename);
rename(outfilename,filename);
return 0;
}
/*
*驱动程序,这里使用了WIN32API,你可以替换成你的编译器提供的文件查找函数.
*/
int main(int argc,char *argv[])
{
if(argc>1) //至少有一个输入
{
WIN32_FIND_DATA FindFileData;
//处理通配符 * ?
HANDLE hFind=FindFirstFile(argv[1],&FindFileData);
if(-1!=(int)hFind)
{
strext(FindFileData.cFileName,argv[2]);
while(FindNextFile(hFind,&FindFileData))
strext(FindFileData.cFileName,argv[2]);
puts("\n---------------------------完成----------------------\n");
FindClose(hFind);
}
else
{
printf("输入文件%s无效。\n",argv[1]);
}
}
else
{
printf("本程序将源代码中的字符串用宏替换,并自动生成宏头文件\n");
printf("用法:strext <输入源文件> [输出头文件]\n");
printf("例子:strext *.c strhead.h\n");
}
getch();
return 0;
}