源代码中的汉子和全角字符的提取方法

/* 在DOS下或者单片机应用中,要显示较少的汉字和全角字符,为了节省空间,通常是建立小字库。而建立小字库第一步就是提取程序中需要显示的汉字。

 

由于是在源程序中检索,必须考虑绕过程序中用于注释的汉字。提取C语言中的全角字符简单流程如下:

 

开始读取->是注释符->绕过注释->否则读取字符

 

TC支持的注释只有/*    */,而VC支持//,要区别对待。找到/*之后,直接跳到下一个*/,找到//则绕过一行。

 

每找到一个字符还是判断,是否和前面已找到的字符重复,如果重复则跳过它。

 

下面的程序通过TC3.0 和VC6支持编译。并且适用于TC和VC源程序,如果要适用其它语言,稍作修改即可。

*/

 

 

#include<stdio.h>
#include<stdlib.h>
#define MAX 10000 /* 指定最半角字符个数[必须为2的倍数] */

unsigned char hztq[MAX]={0},hz[2]={0},*Phztq=hztq;

int main(int argc,char *argv[]){
 short int find(void); /* 用于查找数组hztq中有没有hz中储存的相同的汉字,若有返回1,若没有返回0 */ 
    FILE *Fc,*Fdat;
 char c;        /* 由于文件结束标志EOF为-1,所以这里c定义为char */
 short int end,flag,flag1,n; /* 设置哨兵 n用于记录找到的全角字数 */

 if(argc!=3){
  printf("Invalid format! Please enter the following manner: /nhztq.exe filename.c filename.dat");
  exit(0);
 }


    if((Fc=fopen(argv[1],"rb"))==NULL){ /* 打开源文件 */
        printf("Can't open %s file!",argv[1]);
        exit(0);
 }
    if((Fdat=fopen(argv[2],"wb"))==NULL){/* 打开目的文件 */
        printf("Can't open %s file!",argv[2]);
        exit(0);
    }

 end=flag=flag1=n=0;    /* 初始化变量 */

 while(!end){
  c=fgetc(Fc);      /* 读取一个字节 */
  if(c==EOF)
   break;
  if(c==0x2f&&!flag){  /* 识别斜杠,以便绕过注释行 */
    flag=1;     /* 如果是前一个斜杠 */
    continue;    /* 超过本次循环 */
  }
  if(flag){
   flag=0;
   if(c==0x2f){     /* 如果还是斜杠 */
    end=1;
    while((c=fgetc(Fc))!=EOF){ /* 继续读取 */
     if(c==0xa){    /* 直到遇到到换行 */
      end=0;    /* 解除哨兵 */
      break;    /* 跳出循环 */
     }
    }
   }
   else if(c==0x2a){   /* 如果是*号 */
    end=1;
    while((c=fgetc(Fc))!=EOF){ /* 继续读取 */
     if(c==0x2a&&!flag1){/* 直到遇到*号 */
      flag1=1;
      continue;  /* 跳到下一次循环 */
     }
     if(flag1){
      flag1=0;  /* 解除哨兵 */
      if(c==0x2f){ /* 如果*号后面接着斜杠 */
       end=0;  /* 解除哨兵 */
       break;  /* 跳出循环 */
      }
     }
    }
   }
  }
  else if(c&0x80){   /* 若读取到的字符是全角字符的首字节,继续读下一个字节 */
   hz[0]=c;
   c=fgetc(Fc);
   if(c!=EOF)
    hz[1]=c;
   else
    break;
   if(!find()){
    *Phztq=hz[0];
    ++Phztq;
    *Phztq=hz[1];
    ++Phztq;
    ++n;
    if(n%10==0)printf(".");
    if(n>MAX/2){  /* 若找到的字超过数据储存上限 */
     printf("/nExceed limit!/a/nLimit is %d full-width characters./n",MAX/2);
     break;
    }

   }
  }
 }
 if(n>0)          /* 将字符写入文件 */
  fwrite(hztq,2,n,Fdat);
 printf("/nFound a total of %d full-width characters.",n);
    printf("/nCollect is completed.");
    fclose(Fc);
 fclose(Fdat);
    return 1;
}

short int find(void){
 unsigned char *p,*p1;
 for(p=hztq;p<Phztq;p+=2){
  if(*p==hz[0]){
   p1=p+1;
   if(*p1==hz[1])
    return 1;
  }
 }
 return 0;
}

 

/* 转载请注明出处 http://blog.csdn.net/PMind */

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值