用C语言实现常见的三种中文内码转换
常见的中文内码一般有gb2312(简体中文),gbk和台湾那边用的big5(繁体中文),有时候看一些台湾编程论坛里的资料,都是乱码,如果在ie中浏览,则要求安装繁体字库的支持。网上也有很多中文内码的转换工具,什么专家,大师,巨匠之类所有光辉灿烂的名字都被使用了,但是在自己的程序中集成这些功能岂不是更好。以前曾广泛流传过使用码表来转换中文内码的code,但毕竟不完美,而且还要携带或内置一个巨大的表,浪费资源。windows中提供了multibytetowidechar和widechartomultibyte两兄弟函数,足可以搞定这些功能了。
以下四个函数分别实现:
大五码转gbk码/gbk转大五码
gb2312码转gbk码/gbk码转gb2312码
于是有人要问了,为什么没有gb2312转big5和big5转gb2312呢,我们有gbk,可以做一下中转啊。可以将gb2312转成gbk,再将gbk转成big5,反之亦然。如果你嫌麻烦,可以自己写一个gb2big5/big52gb。
//---------------------------------------------------------------------------
// 大五码转gbk码:
// い地チ㎝瓣 --> 中華人民共和國
void __fastcall big52gbk(char *szbuf)
{
if(!strcmp(szbuf, \"\"))
return;
int nstrlen = strlen(szbuf);
wchar_t *pws = new wchar_t[nstrlen + 1];
try
{
int nreturn = multibytetowidechar(950, 0, szbuf, nstrlen, pws, nstrlen + 1);
bool bvalue = false;
nreturn = widechartomultibyte(936, 0, pws, nreturn, szbuf, nstrlen + 1, \"?\", &bvalue);
szbuf[nreturn] = 0;
}
__finally
{
delete[] pws;
}
}
//---------------------------------------------------------------------------
// gbk转大五码
// 中華人民共和國 --> い地チ㎝瓣
void __fastcall gbk2big5(char *szbuf)
{
if(!strcmp(szbuf, \"\"))
return ;
int nstrlen = strlen(szbuf);
wchar_t *pws = new wchar_t[nstrlen + 1];
try
{
multibytetowidechar(936, 0, szbuf, nstrlen, pws, nstrlen + 1);
bool bvalue = false;
widechartomultibyte(950, 0, pws, nstrlen, szbuf, nstrlen + 1, \"?\", &bvalue);
szbuf[nstrlen] = 0;
}
__finally
{
delete[] pws;
}
}
//----------------------------------------------------------------------------
// gb2312码转gbk码
// 中华人民共和国 --> 中華人民共和國
void __fastcall gb2gbk(char *szbuf)
{
if(!strcmp(szbuf, \"\"))
return;
int nstrlen = strlen(szbuf);
word wlcid = makelcid(makelangid(lang_chinese, sublang_chinese_simplified), sort_chinese_prc);
int nreturn = lcmapstring(wlcid, lcmap_traditional_chinese, szbuf, nstrlen, null, 0);
if(!nreturn)
return;
char *pcbuf = new char[nreturn + 1];
try
{
wlcid = makelcid(makelangid(lang_chinese, sublang_chinese_simplified), sort_chinese_prc);
lcmapstring(wlcid, lcmap_traditional_chinese, szbuf, nreturn, pcbuf, nreturn + 1);
strncpy(szbuf, pcbuf, nreturn);
}
__finally
{
delete[] pcbuf;
}
}
//---------------------------------------------------------------------------
// gbk码转gb2312码
// 中華人民共和國 --> 中华人民共和国
void __fastcall gbk2gb(char *szbuf)
{
if(!strcmp(szbuf, \"\"))
return;
int nstrlen = strlen(szbuf);
word wlcid = makelcid(makelangid(lang_chinese, sublang_chinese_simplified), sort_chinese_big5);
int nreturn = lcmapstring(wlcid, lcmap_simplified_chinese, szbuf, nstrlen, null, 0);
if(!nreturn)
return;
char *pcbuf = new char[nreturn + 1];
try
{
wlcid = makelcid(makelangid(lang_chinese, sublang_chinese_simplified), sort_chinese_big5);
lcmapstring(wlcid, lcmap_simplified_chinese, szbuf, nreturn, pcbuf, nreturn + 1);
strncpy(szbuf, pcbuf, nreturn);
}
__finally
{
delete []pcbuf;
}
}
//---------------------------------------------------------------------------
// 测试代码
void __fastcall tform1::button1click(tobject *sender)
{
char szbuf[255];
// 从gb2312转到gbk
strcpy(szbuf, edit1->text.c_str());
gb2gbk(szbuf);
edit2->text = string(szbuf);
// 从gb2312转到big5,通过gbk中转
strcpy(szbuf, edit1->text.c_str());
gb2gbk(szbuf);
gbk2big5(szbuf);
edit3->text = string(szbuf);
}
注意,请不要使用string类的c_str()作为上述几个函数的传入参数。