转载请注明出处:http://blog.csdn.net/yf210yf/article/details/7850472
繁体为什么分为乱码和非乱码的。现在总算搞清楚了
看起来是乱码那种叫Big5,非乱码的叫GBK繁体
GBK包括了简体和繁体
乱码的是Big5
GB2312字集是简体字集,全称为GB2312(80)字集,共包括国标简体汉字6763个。
BIG5字集是台湾繁体字集,共包括国标繁体汉字13053个。
GBK字集是简繁字集,包括了GB字集、BIG5字集和一些符号,共包括21003个字符。
一般来说,如果您在简体中文操作系统中使用繁体字,选GBK码繁体中文;如果您在繁体中文操
作系统中使用繁体字,选Big5码繁体中文。
不知道会不会写的很多,总之先补一下知识:
(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 MS、MingLiU、PMingLiU等字体支持显示这个字符集。微软拼音输入法2003、全拼、紫光拼音等输入法,能够录入如镕镕炁夬喆嚞姤赟赟龑昳堃慜靕臹等GBK简繁体汉字。
BIG-5 (繁体中文)与GB-2313 (简体中文),编码不相兼容,字符在不同的操作系统中便产生乱码。文本文字的简体与繁体(文字及编码)之间的转换,可用BabelPad、TextPro或Convertz之类的转码软件来解决。若是程序,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 XP或2003简体中文版就自带有这个字体。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万多个汉字。
国际语言编码标准来使用。
(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 [ ]来存放“中文”时有什么不同
而要正常打印宽字节,需要
setlocale (LC_ALL,"");
wchar_t wstr[] = L"中文";
wcout<<wstr<<endl;
那关于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: $
CString cStr1;
cStr1.Format( "%s",rlt);
用到了CString 和 char *的转换
CString 转换成char*:
char* ch = cstring.GetBuffer(cstring.GetLength());
char*转换成CString:
CString.Format( "%s ",ch);
char* UnicodeToBIG5(const wchar_t* szUnicodeString);
char* UnicodeToGB2312(const wchar_t* szUnicodeString);
wchar_t* GB2312ToUnicode(const char* szGBString);
char* GB2312ToBIG5(const char* szGBString);