`
yiheng
  • 浏览: 155680 次
社区版块
存档分类

VC----实现汉字简繁转换

    博客分类:
  • VC++
阅读更多

转载请注明出处:http://blog.csdn.net/yf210yf/article/details/7850472

不知道会不会写的很多,总之先补一下知识:

(1)计算机汉字编码简介

关于汉字编码

为进行信息交换,各汉字使用地区都制订了一系列汉字字符集标准。

① GB2313字符集,收入汉字6763个,符号715个,总计7478个字符,这是大陆普遍使用的简体字符集。楷体-GB2313、仿宋-GB2313、华文行楷等市面上绝大多数字体持显示这个字符集,亦是大多数输入法所采用的字符集。市面上绝大多数所谓的繁体字体,其实采用的是GB-2313字符集简体字的编码,用字体显示为繁体字,而不是直GBK字符集中繁体字的编码,错误百出。

② BIG-5字符集,收入13060个繁体汉字,808个符号,总计13868个字符,目前普遍使用于台湾、香港等地区。台湾教育部标准宋体楷体等港台大多数字体支持这个字符集的显示。

③ GBK字符集,又称大字符集(GB=GuóBiāo国标,K=扩展),包含以上两种字符集汉字,收21003个汉字,882个符号,共计21885个字符,包括了中日韩(CJK)统一汉20902个、扩展A(CJK Ext-A) 中的汉字52个。Windows 95\98简体中文版就带有这个GBK.txt文件。宋体、隶书、黑体、幼圆、华文中宋、华文细黑、华文楷体、标楷(DFKai-SB)Arial Unicode MSMingLiUPMingLiU等字体支持显示这个字符集。微软拼音输入法2003、全拼、紫光拼音等输入法,能够录入如镕镕炁夬喆嚞姤赟赟龑昳堃慜靕臹等GBK简繁体汉字。


BIG-5 (繁体中文)GB-2313 (简体中文),编码不相兼容,字符在不同的操作系统中便产生乱码。文本文字的简体与繁体(文字及编码)之间的转换,可用BabelPad
TextProConvertz之类的转码软件来解决。若是程序,Windows XP操作系统,可用Microsoft AppLocale Utility 1.0解决;Windows 2000的操作系统,大概只有用:中文之星、四通利方、南极星、金山快译之类的转码软件方能解决了。

④ GB18030字符集,包含GBK字符集、CJK Ext-A 全部6582个汉字,共计27533个汉字。宋体-18030、方正楷体(FZKai-Z03)、书同文楷体(MS Song)宋体(ht_cjk+)、香港华康标准宋(DFSongStd)、华康香港标准楷体、CERG Chinese Font、韩国New Gulim,以及微软Windows Vista操作系统提供的宋黑楷仿宋等字体亦支持这个字符集的显示。Windows 98支持这个字符集,以下的字符集则不支持。手写输入法逍遥笔4.0版支持GB18030字符集及方正超大字符集汉字的录入。


⑤ 方正超大字符集,包含GB18030字符集、CJK Ext-B中的36862个汉字,共计64395个汉字。宋体-方正超大字符集支持这个字符集的显示。Microsoft Office XP2003简体
中文版就自带有这个字体。Windows 2000的操作系统需安装超大字符集支持包Surrogate更新


⑥ ISO/IEC 10646 / Unicode字符集,这是全球可以共享的编码字符集,两者相互兼融,涵盖了世界上主要语文的字符,其中包括简繁体汉字,计有:CJK统一汉字20902
个,CJK Ext-A 6582个,Ext-B 42711个,共计70195个汉字。SimSun-ExtB(宋体)MingLiU-ExtB(细明体)能显示全部Ext-B汉字。至今尚无单独一款字体能够显示全部70195个汉字,但可用海峰五笔、新概念五笔、仓颉输入法世纪版、新版的微软新注音、仓颉输入法 6.0 (单码功能)等输入法录入。Ext-C还有2万多个汉字。

关于Unicode
由于各国国家标准字集所收的汉字字数、常用字的差异,虽然象中国两岸GB/BIG5字集常用字基本类似,转换后阅读并不成问题,但是这种编码转换的混乱关系,对文字交 流始终是一种障碍。因此相关国家的标准化组织和文字工作者经过共同努力,终于在 93 年完成了包含中日韩 (CJK) 汉字的 Unicode  汉字标准 ISO 10646.1 。  Unicode 是完全双字节 表示的多国文字编码体系,编码空间 0x0000-0xFFFF
ISO 10646.1 汉字标准使用编码 0x4E00-9FA5 ,共包含 20902 个汉字。其中: 大陆 (S) 提出的汉字 17124 个,台湾 (T) 提出的 汉字 17258 ; S T 的并集,即中国 (C) 提出的汉字为 20158 个。 日本 (J) 提出的汉字为 12157 个,中国未提出的 690 (Ja);  韩国 (K) 提出的汉字为 7477 个,其中中国未提出的 90 (Ka); Ja Ka 并集共 744 字。 支持 Unicode 编码的相关电脑系统软件,如 Unix, Win95 已有推出,但是由于 Unicode ASCII 码是用双字节编码 ( 即一般电脑系统中的单字节 ASCII 前加  0x00) ,同时其汉字编码与各国的现有编码也不兼容,造成现有的软件和数据不能直接使用,所以目前完全使用 Unicode 软件系统的用户并不多,大多数只将它此作为一个

国际语言编码标准来使用。


(2)基本原理

由上述编码知识可知,字体的切换其实就是编码的切换

GB2312<->Unicode<->BIG5

这样一个流程,Unicode充当切换的桥梁。


(3)VC的实现

先上代码再解释:

#include   <iostream> 
#include <atlstr.h>
#include <locale.h>
using   namespace   std; 

char* UnicodeToBIG5(const wchar_t* szUnicodeString);
char* UnicodeToGB2312(const wchar_t* szUnicodeString);
wchar_t* GB2312ToUnicode(const char* szGBString);
char* GB2312ToBIG5(const char* szGBString);

void   main() 
{         
	locale loc( "chs" );//定义“区域设置”为中文方式
	//wchar_t str[]=L"中国";
	char str[100];
	cin>>str;
        char * rlt=GB2312ToBIG5(str);
	CString   cStr1; 
	cStr1.Format( "%s",rlt); 
	setlocale(LC_ALL, ".950");
	cout<<rlt<<endl;
} 

wchar_t* GB2312ToUnicode(const char* szGBString)
{
	UINT nCodePage = 936; //GB2312
	int nLength=MultiByteToWideChar(nCodePage,0,szGBString,-1,NULL,0);
	wchar_t* pBuffer = new wchar_t[nLength+1];
	MultiByteToWideChar(nCodePage,0,szGBString,-1,pBuffer,nLength);
	pBuffer[nLength]=0;
	return pBuffer;
}
//BIG5 转换成 Unicode:
wchar_t* BIG5ToUnicode(const char* szBIG5String)
{
	UINT nCodePage = 950; //BIG5
	int nLength=MultiByteToWideChar(nCodePage,0,szBIG5String,-1,NULL,0);
	wchar_t* pBuffer = new wchar_t[nLength+1];
	MultiByteToWideChar(nCodePage,0,szBIG5String,-1,pBuffer,nLength);
	pBuffer[nLength]=0;
	return pBuffer;
}
//Unicode 转换成 GB2312:
char* UnicodeToGB2312(const wchar_t* szUnicodeString)
{
	UINT nCodePage = 936; //GB2312
	int nLength=WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,NULL,0,NULL,NULL);
	char* pBuffer=new char[nLength+1];
	WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,pBuffer,nLength,NULL,NULL);
	pBuffer[nLength]=0;
	return pBuffer;
}
//Unicode 转换成 BIG5:
char* UnicodeToBIG5(const wchar_t* szUnicodeString)
{
	UINT nCodePage = 950; //BIG5
	int nLength=WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,NULL,0,NULL,NULL);
	char* pBuffer=new char[nLength+1];
	WideCharToMultiByte(nCodePage,0,szUnicodeString,-1,pBuffer,nLength,NULL,NULL);
	pBuffer[nLength]=0;
	return pBuffer;
}
//繁体中文BIG5 转换成 简体中文 GB2312
char* BIG5ToGB2312(const char* szBIG5String)
{
	LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);
	wchar_t* szUnicodeBuff = BIG5ToUnicode(szBIG5String);
	char* szGB2312Buff = UnicodeToGB2312(szUnicodeBuff);
	int nLength = LCMapString(lcid,LCMAP_SIMPLIFIED_CHINESE, (LPCSTR)szGB2312Buff,-1,NULL,0);
	char* pBuffer = new char[nLength + 1];
	LCMapString(0x0804,LCMAP_SIMPLIFIED_CHINESE,(LPCSTR)szGB2312Buff,-1,pBuffer,nLength);
	pBuffer[nLength] = 0;

	delete[] szUnicodeBuff;
	delete[] szGB2312Buff;
	return pBuffer;
}
//简体中文 GB2312 转换成 繁体中文BIG5
char* GB2312ToBIG5(const char* szGBString)
{
	LCID lcid = MAKELCID(MAKELANGID(LANG_CHINESE,SUBLANG_CHINESE_SIMPLIFIED),SORT_CHINESE_PRC);
	int nLength = LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGBString,-1,NULL,0);
	char* pBuffer=new char[nLength+1];
	LCMapString(lcid,LCMAP_TRADITIONAL_CHINESE,szGBString,-1,pBuffer,nLength);
	pBuffer[nLength]=0;
	wchar_t* pUnicodeBuff = GB2312ToUnicode(pBuffer);
	char* pBIG5Buff = UnicodeToBIG5(pUnicodeBuff);
	delete[] pBuffer;
	delete[] pUnicodeBuff;
	return pBIG5Buff;
}

运行的效果图:

输入:简体中文

c输出:繁体中文


转载请注明出处:http://blog.csdn.net/yf210yf/article/details/7850472

(4)详解

假如您是高手,请跳过,下面的讲解可能对您很基础。

1>locale loc( "chs" );//定义“区域设置”为中文方式

2>wchar_t定义的是宽字节

所谓的多字节与宽字节,就是指ASCII字符和Unicode字符。前者占一个字节,后者占两个字节。
Win2000以后的系统从底层支持Unicode字符。就现在来看,尽量要要用Unicode字符,这样可以提高程序效率,避免系统在内部进行转换。Win2000以后的系统中,所有API函
数只接受Unicode字符,如果传入ASCII字符,系统会自动把它转换成Unicode字符,再调用函数。

例如:

‘中’   Unicode码值:U+4E2D  UTF-8 编码 e4 b8 ad
‘文’   Unicode码值:U+6587  UTF-8 编码  e6 96 87

我们需要理解用char[ ]和wchar_t [ ]来存放“中文”时有什么不同

    char    str[]="中文";
    wchar_t wstr[] 
= L"中文";    

我们使用gdb这个强大的工具来查看str[]和wst[]中究竟都存放了哪些值(请注意颜色之间的对应关系)

(gdb) x /8xb &str
0xbf83decd:     0xe4    0xb8    0xad    0xe6    0x96    0x87    0x00    0xf0
(gdb) x 
/12xb &wstr
   0xbf83dec0:     0x2d    0x4e    0x00    0x00    0x87    0x65    0x00    0x00
   0xbf83dec8:     0x00    0x00    0x00    0x00

不难看出,char str[ ]中存储的是“中文"的UTF-8编码,这是因为我的机器的locale是zh_CN.UTF-8,程序源文件的自然采用的是UTF-8编码,因此编译器 在处理 char str[ ]="中文"; 时,t它对str[]所做得初始化实际上可以理解成    char str[ ]={ 0xe4,0xb8,0xad,0xe6,0x96,0x87,0x00}

而wchar_t wstr[ ]中存放的是“中文"的Unicode码值,这符合C标准对宽字符的定义。这里需要解释的是C标准中规定宽字符是16 bit的字符,而从GNU glibc 2.2开始,类型wchar_t只用于存放32-bit的ISO 10646码值(你可以粗略的把ISO 10646理解成Unicode,尽管它们并不是一回事),而独立于当前使用的locale;因此在上面的输出中,我们看到每个Unicode码值用 32bit表示,而不是16bit。
参考:http://blog.csdn.net/lovekatherine/article/details/1868724

而要正常打印宽字节,需要

setlocale (LC_ALL,"");
wchar_t wstr[] = L"中文";    
wcout<<wstr<<endl;

注意setlocale (LC_ALL,"");很重要,否则会输出??

那关于setlocale的介绍如下

setlocale

配置地域化信息。

语法:   char * setlocale ( int category, const char * locale );

返回值: 字符串

函数种类: 操作系统与环境

内容说明

本函数用来配置地域的信息,设置当前程序使用的本地化信息。参数 category 有下列的选择:

    * LC_ALL 包括下面的全项选项都要。
    * LC_COLLATE 配置字符串比较,PHP 目前尚未实作出来本项。
    * LC_CTYPE 配置字符类别及转换。例如全变大写 strtoupper()。
    * LC_MONETARY 配置金融货币,PHP 目前尚未实作。
    * LC_NUMERIC 配置小数点后的位数。
    * LC_TIME 配置时间日期格式,与 strftime() 合用。

而参数 locale 若是空字符串 "",则会使用系统环境变量的 locale 。若 locale 为零(NULL),则不会改变地域化配置,返回当前的地域值,若系统尚未实作则返回 false。

Locales contain information on how to interpret and perform certain input/output and transformation operations taking into consideration location and language specific settings.

Most running environments have certain locale information set according to the user preferences or localization. But, independently of this system locale, on start, all C programs have the "C" locale set, which is a rather neutral locale with minimal locale information that allows the result of programs to be predictable. In order to use the default locale set in the environment, this function can be called with "" as the locale parameter.

The locale set on start is the same as setlocale(LC_ALL,"C") would set.
The entire default locale can be set by calling setlocale(LC_ALL,"");

C程序开始的时候的设置和 setlocale(LC_ALL,"C")相同

使用系统默认的设置调用setlocale(LC_ALL,"");

The parts of the current locale affected by a call to this function are specified by parameter category.
Return Value
On success, A pointer to a C string identifying the locale currently set for the category. If category is LC_ALL and different parts of the locale are set to different values, the string returned gives this information in a format which may vary between compiler implementations.

例子:

/* setlocale example */
#include <stdio.h>
#include <time.h>
#include <locale.h>

int main ()
{
  time_t rawtime;
  struct tm * timeinfo;
  char buffer [80];

  struct lconv * lc;

  time ( &rawtime );
  timeinfo = localtime ( &rawtime );

  int twice=0;

  do {
    printf ("Locale is: %s/n", setlocale(LC_ALL,NULL) ); //使用NULL参数,获取当前配置

    strftime (buffer,80,"%c",timeinfo);
    printf ("Date is: %s/n",buffer);

    lc = localeconv ();
    printf ("Currency symbol is: %s/n-/n",lc->currency_symbol);

    setlocale (LC_ALL,"");
  } while (!twice++);
  
  return 0;
}

One of the possible outputs when the previous code is run is:

Locale is: C
Date is: 01/15/07 13:33:47
Currecy symbol is: 
-
Locale is: English_United States.1252
Date is: 1/15/07 1:33:47 PM
Currency symbol is: $

3)

CString   cStr1; 

cStr1.Format( "%s",rlt); 

用到了CString 和 char *的转换

CString   转换成char*: 
char*   ch   =   cstring.GetBuffer(cstring.GetLength()); 
char*转换成CString: 
CString.Format( "%s ",ch); 

4>在这几个函数中还涉及一个问题

char* UnicodeToBIG5(const wchar_t* szUnicodeString);
char* UnicodeToGB2312(const wchar_t* szUnicodeString);
wchar_t* GB2312ToUnicode(const char* szGBString);
char* GB2312ToBIG5(const char* szGBString);

const char*, char const*, char*const的区别

char * const cp     : 定义一个指向字符的指针常数,即const指针
const char* p       : 定义一个指向字符常数的指针
char const* p       : 等同于const char* p

5>MultiByteToWideChar 接口
字面意思可以看出是多字节转宽字节
//Big5 -> Unicode
//用MultiByteToWideChar来返回字符个数
lngLen = MultiByteToWideChar(950, 0, strSource, -1, NULL, 0) 'MultiByteToWideChar 返回的是字符个数,乘 2 才是所需要分配的空间
lngLen = lngLen - 1 'MultiByteToWideChar 返回的个数多了1

strUnicode = String(lngLen * 2, 0)
lngRet = MultiByteToWideChar(950, 0, strSource, -1, strUnicode, lngLen)

//Unicode -> GB 繁体
lngLen = WideCharToMultiByte(936, 0, strUnicode, -1, NULL, 0, NULL, 0)
//lngLen = Len(strUnicode)
strGBKT = String(lngLen, 0)lngLen = WideCharToMultiByte(936, 0, strUnicode, -1, strGBKT, lngLen, NULL, 0)
思路是先
先用MultiByteToWideChar来返回字符个数



然后转换成新的字符编码


分享到:
评论

相关推荐

    简繁转换工具-非常好用

    简繁转换工具是一种重要的软件应用,它主要用于将简体中文字符转换为繁体中文字符,或者反过来,将繁体中文转换为简体中文。在不同的使用场景中,这种工具非常实用,尤其对于需要处理多种中文编码格式的用户来说,它...

    Office Word 2007-2013插件 自动简繁转换(MyConverter) 2013-3-28

    1.使用AddinInstallerO.exe安装自动简繁转换的插件(Plugin) 2.可以在加载项看到安装的插件命令,请等候安装完成 ...5.功能是选取的区域自动判定简繁实现简繁转换 6.特色就是转换的时候不会改变文字原有格式

    论坛bbs--简繁转换 奖章插件

    简繁转换技术基于中文字符集的转换规则,例如GB2312、GBK、Big5、UTF-8等编码体系,通过算法实现简体字与繁体字之间的相互转换。这种技术的应用使得无论用户使用哪种字符集,都能在论坛上顺畅地阅读和交流。通常,...

    简繁转换单元,实现简繁繁简的转换

    标题提到的"简繁转换单元"是指一个专门用于实现简体中文与繁体中文之间转换的功能模块。这个单元能够帮助用户在不同的语言环境下顺畅地进行文本交流,尤其对于需要跨地区沟通或者处理历史文献的人来说非常实用。 ...

    两岸通--简繁字互转源代码

    《两岸通--简繁字互转源代码》是一款专门用于简体字与繁体字转换的软件开发资源,它的核心功能在于提供高效准确的汉字字符集转换算法,以实现中文文字在简体与繁体之间的无缝切换。这款源代码对于需要处理简繁体转换...

    中文简繁转换(C#)

    总的来说,中文简繁转换在C#和VB.NET中可以通过编码转换、字典映射或使用现成的库来实现。开发者可以根据需求选择合适的方法,以满足不同场景的应用。无论是简单的字符替换还是复杂的语义理解,C#和VB.NET都提供了...

    php -> 简繁转换

    简繁转换的核心在于理解汉字的两种主要编码形式:GB2312(简体中文)和Big5(繁体中文)。GB2312是简体中文的标准编码,而Big5则用于传统繁体中文。在现代的Unicode编码(如UTF-8)环境中,这两种编码可以相互转换,...

    简繁转换器-java

    用java写的简繁转换器,挺好用的,还可以实现简单的统计字数以及把.xls文件转化为.txt文件的功能

    Office 2003 简繁转换加载宏

    Office 2003 简繁转换加载宏Office 2003 简繁转换加载宏Office 2003 简繁转换加载宏

    简繁中文转换,简繁中文转换.rar

    简繁中文转换是计算机技术中一个重要的语言处理领域,它涉及到中文字符集的转换,以适应不同地区和用户的阅读习惯。简体中文和繁体中文是汉字的不同书写形式,简体字在中国大陆、新加坡等地广泛使用,而繁体字则在...

    Microsoft Excel档案简繁转换工具--V2.0

    【Microsoft Excel档案简繁转换工具 V2.0】是一款专为处理Excel文件中的简体与繁体中文转换问题而设计的高效工具。该工具适用于那些需要在简体和繁体中文之间频繁切换的工作场景,例如跨地区的企业协作、学术研究或...

    VC 汉字简繁转换、文件分割、隐藏加密软件源码.rar

    一个集成了汉字简繁转换、文件加密等功能的VC 软件源码,这个软件包括了汉字的繁简转换、文件加密、DLL/OCX控件注册、定时关机,桌面宠物、文件分割、文件隐藏、光驱弹出等功能,一个小小的软件,集成了这么多小功能...

    VB簡繁轉化(简繁转换)

    在进行简繁转换时,理解汉字字符集至关重要。简体中文主要使用GB2312或GBK字符集,而繁体中文则通常使用Big5字符集。VB作为编程语言,可以通过内置的字符串处理函数或者第三方库来实现字符集间的转换。转换过程包括...

    汉字简繁转换软件,非常实用的文字工具,不容错过,值得收藏

    汉字简繁转换软件是IT行业中一个非常重要的工具,尤其对于那些需要在简体与繁体汉字之间频繁切换的用户来说,它具有极高的实用价值。这类软件的主要功能就是实现简体字与繁体字之间的相互转换,使得文字信息在不同...

    简繁转换.alfredworkflow

    alfred workflow简繁中文转换工具。python简繁转换工具

    twTrCn-简繁转化php插件

    "twTrCn-简繁转化php插件"是一个专门设计用于PHP开发环境的工具,其主要功能是实现中文字符的简体与繁体之间的转换。这个插件的核心原理是基于字符映射,通过预先定义好的字符对照表,将输入的繁体中文字符串转化为...

    汉子简繁转换器,支持汉子转换,小写英语转Pascal, 暂时不支持word和excel

    转换器通过内部存储的映射关系,将输入的简体或繁体汉字与相应的另一种形式的汉字对应起来,实现转换。对于未包含在映射表中的特殊字符,转换器可能无法进行转换,这也是为什么描述中提到“暂时不支持word和excel”...

    php简繁互转插件

    “php简繁互转插件”就是这样一个工具,它能够帮助开发者轻松实现简体中文到繁体中文,以及繁体中文到简体中文的转换。全智能的特性意味着它不仅支持单个字符的转换,还能处理完整的句子和段落,确保语义的准确性和...

    游戏简繁转换工具w2kxpcjk2

    总之,“w2kxpcjk2”作为一款高效实用的游戏简繁转换工具,极大地扩展了玩家的游戏库,使他们能在简体中文环境下体验到更多经典游戏的魅力。然而,用户在使用时仍需谨慎,了解其可能存在的局限性和风险,以确保顺利...

    office2003简繁转换插件(PPT,EXCEL也能简繁转换了)

    Office 2003简繁转换插件是微软官方为用户提供的一个重要工具,它使得在Office 2003环境中进行简体与繁体中文之间的转换变得更加便捷。这个插件适用于Word、Excel以及PowerPoint等多个应用程序,使得用户无需离开...

Global site tag (gtag.js) - Google Analytics