如何将文本文件转换成UTF-8格
解决方案 »
- CSDN发帖老是蓝屏 求ATI HD4200稳定驱动
- vc单文档多视图转换后不能刷新问
- 请教那位有关于图象轮廓提取、跟踪的算法及程序?十万火急。
- 怎么读取安全数组速度最快?
- 请问在VC中如何查询注册表中是否有某一个值?
- 666分求转账查询CODE,分不够可以再加
- 请问有哪位专家会用 CdbDBEngine ?
- 求教 单引号 和 双引号 的作用和在使用中的区别
- 我想把各位对我问题的回答或者其他帖子保存,发现现在不能用“文件-另存为”了,ie说使用 XSL 样式表无法查看 XML 输入。 各位谁知道比
- makefile 知识
- 大家帮我看看这个socket程序怎么编译不通过?
- 请问YUV转JPEG是否是要先转成BMP?请给出算法或者例子。谢谢了。
用ANSI储存:12 Bytes
用Unicode/UCS2储存:24 Bytes + 2 Bytes(header)
用UCS4储存:48 Bytes + 4 Bytes(header) 以"我是中国人"为例
用ANSI储存:10 Bytes
用Unicode/UCS2储存:10 Bytes + 2 Bytes(header)
用UCS4储存:20 Bytes + 4 Bytes(header) 由此可见直接以Unicode/UCS的原始形式来储存是一种极大的浪费,而且也不利于互联网的传输(中文稍为合算一点^_^)。 有见及此,Unicode/UCS的压缩形式--UTF8出现了,套用官方网站的首句话『UTF-8 stands for Unicode Transformation Format-8. It is an octet (8-bit) lossless encoding of Unicode characters.』,由于UTF也适用于编码UCS,故亦可称为『UCS transformation formats (UTF)』 UTF8是以8bits即1Bytes为编码的最基本单位,当然也可以有基于16bits和32bits的形式,分别称为UTF16和UTF32,但目前用得不多,而UTF8则被广泛应用在文件储存和网络传输中。
编码原理先看这个模板: UCS-4 range (hex.) UTF-8 octet sequence (binary)
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx 0001 0000-001F FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
0020 0000-03FF FFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
0400 0000-7FFF FFFF 1111110x 10xxxxxx ... 10xxxxxx编码步骤:
1) 首先确定需要多少个8bits(octets)
2) 按照上述模板填充每个octets的高位bits
3) 把字符的bits填充至x中,字符顺序:低位→高位,UTF8顺序:最后一个octet的最末位x→第一个octet最高位x
4) 解码的原理一样。实例:(留意每个bit的颜色,粗体字为模板内容)UCS-4 |UTF-8
-----------------------------------------------------------------------------
HEX BIN Bytes| BIN HEX Bytes
0000 000A 00001010 4 | 00001010 0A 1
0000 0099 10011001 4 | 11000010 10011001 C2 99 2
0000 8D99 10001101 10011001 4 | 11101000 10110110 10011001 E8 B6 99 3 不知大家看懂了没有,其实不懂也无所谓,反正又不用自己算,程式可以完全代劳。 以UTF8格式储存的文件档首标识为EF BB BF。
效率 从上述编码原理中得出的结论是:
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的都是些非常少用的文字符号。官方网站:http://www.utf8.com/
你可以通过WideCharToMultiByte和MultiByteToWideChar实现转化的操作,也可以通过
Unicode.org上的对照表自己做codepageUTF-8是UNICODE的压缩方式,其实对英文比较经济,只需要一个字节的空间,而对于中文则
需要3个字节,比UNICODE还费。转化的方式同样可以使用上面的2个函数,也可以载网上查相应的代码,不是很复杂。
LPWSTR CStrHandler::TransA2W(LPCSTR pszSrc,UINT uCodePage)
{
LPWSTR lpwStr = NULL;
try
{
int iLen = strlen(pszSrc);
int iSize = sizeof(WCHAR) * iLen + 1;
lpwStr = new WCHAR[iSize];
iSize = ::MultiByteToWideChar(uCodePage, 0, pszSrc,
iLen + 1, lpwStr, iSize);
}
catch(...)
{
if(lpwStr != NULL)
delete lpwStr;
lpwStr = NULL;
}
return lpwStr;
}LPTSTR CStrHandler::TransW2A(LPWSTR src,UINT uCodePage)
{
int nSrcLen = src != NULL ? wcslen(src) * 2 : 0;
if (nSrcLen == 0) return NULL; LPTSTR dest = new CHAR[nSrcLen + 1];
int result = ::WideCharToMultiByte(uCodePage, 0, src, -1,
dest, nSrcLen + 1, NULL, NULL);
if (result > 0)
dest[result-1] = '\0'; return dest;
}
BY_HANDLE_FILE_INFORMATION fi;
::GetFileInformationByHandle(hFile,&fi);
pBuf = new char[fi.nFileSizeLow + 1];
::SetFilePointer(hFile,0,0,FILE_BEGIN);
::ReadFile(hFile,pBuf,fi.nFileSizeLow,&dwSize,NULL);
pBuf[dwSize] = '\0'; LPWSTR pData = TransA2W(pBuf, CP_ACP);
dwSize = wcslen(pData) * sizeof(pData[0]);
delete pBuf;
pBuf = TransW2A(pData, CP_UTF8);
dwSize = strlen(pBuf);
::SetFilePointer(hFile, 0, 0, FILE_BEGIN);
::WriteFile(hFile, pBuf, dwSize, &dwSize, NULL);