您的位置:首页 > 其它

UTF--->Unicode--->Ansi 这个最终返回的中文字符才是正确的,否则中文是乱码

2015-05-12 13:30 302 查看
具体区别:

ANSI:16384个字符。这就是ANSI字符标准。英文一个字节,中文两个字节,是多字节字符串

UNICODE:
使用两个字节对世界上几乎所有的语言进行编码(0x0000-0xFFFF),65536个字符,每种语言的代码段不同,两个字节(英文、中文都是两个字节)所表达的字符是唯一的,所以不同语种可以共存于文本中,解决国际化的问题,是宽字符串

UTF8是Unicode一种压缩形式,英文A在unicode中表示为0x0041,老外觉得这种存储方式太浪费,因为浪费了50%的空间,于是就把英文压缩成1个字节,成了utf8编码,但是汉字在utf8中占3个字节,显然用做中文不如ansi合算,这就是中国的网页用作ansi编码而老外的网页常用utf8的原因。

一、UTF 
   从编码原理中得出的结论是:

  1.每个英文字母、数字所占的空间为1 Byte;

  2.泛欧语系、斯拉夫语字母占2 Bytes;

  3.汉字占3 Bytes。

  由此可见UTF8对英文来说是个非常诱人的方案,但对中文来说则不太合算,无论用ANSI还是 Unicode/UCS2来编码都只用2 Bytes,但用UTF8则需要3 Bytes。

  以下是一些统计资料,显示用UTF8来储存文件每个字符所需的平均字节:

  1.拉丁语系平均用1.1 Bytes;

  2.希腊文、俄文、阿拉伯文和希伯莱文平均用1.7 Bytes;

  3.其他大部份文字如中文、日文、韩文、Hindi(北印度语)用约3 Bytes;
  4.用超过4 Bytes的都是些非常少用的文字符号。

二、Unicode
  Unicode字符集可以简写为UCS(Unicode Character Set)。早期的Unicode标准有UCS-2、UCS-4的说法。UCS-2用两个字节编码,UCS-4用4个字节编码。UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个平面(plane)。每个平面根据第3个字节分为256行 (row),每行有256个码位(cell)。group 0的平面0被称作BMP(Basic Multilingual
Plane)。将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。


 由于每种语言都制定了自己的字符集,导致最后存在的各种字符集实在太多,在国际交流中要经常转换字符集非常不便。因此,提出了Unicode字符集,它固定使用16 bits(两个字节、一个字)来表示一个字符,共可以表示65536个字符。将世界上几乎所有语言的常用字符收录其中,方便了信息交流。标准的Unicode称为UTF-16。后来为了双字节的Unicode能够在现存的处理单字节的系统上正确传输,出现了UTF-8,使用类似MBCS的方式对Unicode进行编码。注意UTF-8是编码,它属于Unicode字符集



Unicode字符集有多种编码形式,而ASCII只有一种,大多数MBCS(包括GB-2312)也只有一种。

13. 如何在Unicode与ANSI之间转换字符串? 

Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串;

               函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串。

char * recongize(IplImage * recimg ,int n,char * temp)
{
tesseract::TessBaseAPI api;
wchar_t *tempchar;
char * resulttemp;
char* text;
char* font1;

if (n==0)
{
font1 = "eng";//数字或字母
}
else
{
font1 = "chi_sim";//中文
}

api.Init(NULL, font1, tesseract::OEM_DEFAULT);
api.SetImage((unsigned char*)(recimg->imageData), recimg->width, recimg->height, recimg->nChannels, recimg->widthStep);
api.SetRectangle(0, 0, recimg->width, recimg->height);

text = api.GetUTF8Text();
tempchar = Utf_8ToUnicode(text);
resulttemp = UnicodeToAnsi(tempchar);
strcpy(temp,resulttemp);

delete []tempchar; //一定要释放这个,因为在Utf_8ToUnicode(text)这个函数时里分配了内存空间
delete []resulttemp;
// szWriteLog("内容 resulttemp---:%s",resulttemp);
return temp;

}

//utf-8转unicode
wchar_t * CIDcardRecogizeDlg::Utf_8ToUnicode(char* szU8)
{
//UTF8 to Unicode
//由于中文直接复制过来会成乱码,编译器有时会报错,故采用16进制形式

//预转换,得到所需空间的大小
int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), NULL, 0);
//分配空间要给'\0'留个空间,MultiByteToWideChar不会给'\0'空间
wchar_t* wszString = new wchar_t[wcsLen + 1];
//转换
::MultiByteToWideChar(CP_UTF8, NULL, szU8, strlen(szU8), wszString, wcsLen);
//最后加上'\0'
wszString[wcsLen] = '\0';
return wszString;
}


//将宽字节wchar_t*转化为单字节char*
char* CIDcardRecogizeDlg::UnicodeToAnsi( const wchar_t* szStr )
{
int nLen = WideCharToMultiByte( CP_ACP, 0, szStr, -1, NULL, 0, NULL, NULL );
if (nLen == 0)
{
return NULL;
}
char* pResult = new char[nLen];

WideCharToMultiByte( CP_ACP, 0, szStr, -1, pResult, nLen, NULL, NULL );

return pResult;

}

wchar_t是C/C++的字符类型,是一种扩展的存储方式,wchar_t类型主要用在国际化程序的实现中,但它不等同于uni编码。uni编码的字符一般以wchar_t类型存储。

char是8位字符类型,最多只能包含256种字符,许多外文字符集所含的字符数目超过256个,char型无法表示。
wchar_t数据类型一般为16位或32位,但不同的C或C++库有不同的规定,如GNU
Libc规定wchar_t为32位[1] ,总之,wchar_t所能表示的字符数远超char型。






内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: