轉:http://blog.csdn.net/exbob/article/details/6542564
對於unicode編碼的字符,可以先將unicode編碼轉換爲GBK編碼,然後利用GBK點陣字庫(gbk.bin)顯示字符。一個比較好的編碼轉換方法是,製作一個按照unicode編碼順序排列的GBK編碼表,直接根據unicode編碼就可以查到對應的GBK編碼,具體的製作方法如下:
1.生成一個unicode字符文件
上以篇文章中已經制作了一個GBK編碼的全字符文件gbk.txt,用記事本打開gbk.txt,然後以unicode編碼另存爲unicode.txt文件。
這樣的話,所有的GBK編碼字符都用unicode編碼保存在unicode.txt中了,可以用winhex打開unicode.txt,會發現前兩個字節是FFFE,這是unicode編碼的標識,要注意後面的unicode編碼是小端存儲。
2.製作unicode轉gbk的文件
這裏要用程序製作一個unicode與gbk編碼相對應的文件,該文件每四個字節爲一組,其中前兩個字節爲unicode編碼,後兩個字節是對應的gbk編碼,兩種編碼都以小端存儲,數據結構如下:
union code
{
unsigned int unigbk;
unsigned short int uni_gbk[2];
unsigned char buffer[4];
};
這個數據結構是以gbk編碼的順序存放在文件uni2gbk.txt中,文件大小爲128764Byte。程序如下:
//由unicode.txt和gbk.txt生成uni2gbk.txt
#include <stdio.h>
int main(void)
{
unsigned char buffer[2];
int count=0;
FILE *fup=0;
FILE *fgp=0;
FILE *fwp=0;
fup=fopen("unicode.txt","rb");
fgp=fopen("gbk.txt","rb");
fwp=fopen("uni2gbk.txt","wb");
fgetc(fup);
fgetc(fup);
while(1)
{
//讀取unicode編碼,寫入uni2gbk.txt
buffer[0]=fgetc(fup);
buffer[1]=fgetc(fup);
fputc(buffer[0],fwp);
fputc(buffer[1],fwp);
//讀取gbk編碼,寫入uni2gbk.txt
buffer[0]=fgetc(fgp);
buffer[1]=fgetc(fgp);
fputc(buffer[1],fwp);
fputc(buffer[0],fwp);
count+=2;
if(count==0xfb7c)
printf("xxxxxxxxx/n");
if(buffer[0]==0xfe && buffer[1]==0xfe)
{
printf("count = %x/n",count);
fclose(fup);
fclose(fgp);
fclose(fwp);
return;
}
}
return 0;
}
3.將uni2gbk.txt排序
用程序將uni2gbk.txt文件中的union code數據結構按照unicode編碼的順序從小到大排序,程序如下:
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE (0x7DBF) //union code的個數
union code
{
unsigned int unigbk;
unsigned short int uni_gbk[2];
unsigned char buffer[4];
};
int main(void)
{
unsigned char flag=1;
unsigned int i=0;
unsigned int j=0;
union code pdata;
union code ndata;
FILE *fp=0;
fp = fopen("uni2gbk.txt","rb+");
for(i=1; i<MAXSIZE && flag==1; i++)
{
flag=0;
for(j=0; j<(MAXSIZE-i); j++)
{
fseek(fp,j*4,0);
fread(pdata.buffer,1,4,fp);
fseek(fp,j*4+4,0);
fread(ndata.buffer,1,4,fp);
if(pdata.uni_gbk[0]>ndata.uni_gbk[0])
{
flag=1;
fseek(fp,j*4,0);
fwrite(ndata.buffer,4,1,fp);
fseek(fp,j*4+4,0);
fwrite(pdata.buffer,4,1,fp);
}
}
printf("i=%d/n",i);
}
fclose(fp);
}
排序後,爲了與沒有排序的uni2gbk.txt區分,將文件名改爲uni2gbkp.txt。
4.刪除無用的編碼
用winhex打開uni2gbkp.txt,可以發現,從0到第0x80EB個字節中的unicode編碼都是0x0020或0x003F,這些都是無用的編碼,它們所對應的gbk編碼也是無用的,都可以刪除。
刪除後,uni2gbkp.txt文件中的union code數據結構的unicode編碼就是從0x00A4開始,以0xFFE5結束。但是這些unicode編碼不是連續的,例如0x00A4之後就是0x00A7,爲了方便查找,需要在不連續的編碼中間用union code填充,對應的gbk編碼部分用0x0000填充,然後將union code中的unicode編碼全部刪除。最後生成uni2gbk.bin文件。程序如下:
#include <stdio.h>
#include <stdlib.h>
union code
{
unsigned int unigbk;
unsigned short int uni_gbk[2];
unsigned char buffer[4];
};
int main()
{
unsigned short int count=0x00A4; //從unicode的0x00A4開始
union code temp;
FILE *frp=0;
FILE *fwp=0;
frp=fopen("uni2gbkp.txt","rb");
fwp=fopen("uni2gbk.bin","wb");
fseek(frp,0x80EC,SEEK_SET); //捨棄uni2gbkp.txt文件的前0x80EC個字節
fread(temp.buffer,1,4,frp);
while(count<=0xffe5) //以unicode的0xffe5結束
{
if(temp.uni_gbk[0]==count) //判斷unicode編碼是否連續
{
fputc(temp.buffer[2],fwp); //將對應的gbk編碼寫入uni2gbk.bin
fputc(temp.buffer[3],fwp);
fread(temp.buffer,1,4,frp);
}
else //不連續的地方填充0
{
fputc(0x00,fwp);
fputc(0x00,fwp);
}
count++;
}
fclose(frp);
fclose(fwp);
return 0;
}
下載:
unicode點陣字庫文件:http://download.csdn.net/source/3362591