Unicode与UTF8相互转化(使用MultiByteToWideChar)
1、简述
最近在发送网络请求时遇到了中文字符乱码的问题,在代码中调试字符正常,用抓包工具抓的包中文字符显示正常,就是发送到服务器就显示乱码了,那就要将客户端和服务器设置统一的编码(UTF-8),而我们程序中 一般用的是Unicode编码,所以这就需要将中文字符转为UTF-8格式的,其他英文字符和数字就不需要转了。下面就讲述一下方法。
2、代码之路
Unicode 转 UTF-8
char* UnicodeToUtf8(const wchar_t* unicode)
{
int len;
len = WideCharToMultiByte(CP_UTF8, 0, unicode, -1, NULL, 0, NULL, NULL);
char *szUtf8 = (char*)malloc(len + 1);
memset(szUtf8, 0, len + 1);
WideCharToMultiByte(CP_UTF8, 0, unicode, -1, szUtf8, len, NULL, NULL);
return szUtf8;
}
int main(int argc, char *argv[])
{
wchar_t* wCharUnicode = L"中国";
char* cCharUtf = UnicodeToUtf8(wCharUnicode);
return 0;
}
结果如下:
我们看到转为UTF-8之后在VS中查看时显示为其他字符。为了验证我们转的字符是否正确,我们可以借用NotePad++这个工具。我们新建一个文件,用NotePad++打开,文件编码默认为ANSI格式,这里显示的跟VS中调试时显示的值是一样的。
我们修改文件编码为UTF-8之后再看一下,是不是显示正常了,所以验证了转换代码正确。
UTF-8 转 Unicode
CString UTF82WCS(const char* szU8)
{
//预转换,得到所需空间的大小;
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';
CString unicodeString(wszString);
delete[] wszString;
wszString = NULL;
return unicodeString;
}
int main(int argc, char *argv[])
{
wchar_t* wCharUnicode = L"中国";
char* cCharUtf = UnicodeToUtf8(wCharUnicode);
CString strUnicode = UTF82WCS(cCharUtf);
return 0;
}
从结果中我们看到,成功地将UTF-8编码转为Unicode编码,代码很简单,还是要多思考,多练,多查阅资料。
给出几个小实例,看一下转换结果。
下面为测试代码:
实例一:
int length;
wchar_t* wCharUnicode = L"中国你好";
length = wcslen(wCharUnicode); // length = 4;
char* cCharUtf = UnicodeToUtf8(wCharUnicode);
length = strlen(cCharUtf); // length = 12;
// 将UTF格式的char*转为CString
CString strUtf(cCharUtf);
length = strUtf.GetLength(); // length = 6;
CString strUnicode = UTF82WCS(cCharUtf);
length = strUnicode.GetLength(); // length = 4;
实例二:
int length;
wchar_t* wCharUnicode = L"中国,你好abc";
length = wcslen(wCharUnicode); // length = 8;
char* cCharUtf = UnicodeToUtf8(wCharUnicode);
length = strlen(cCharUtf); // length = 16;
// 将UTF格式的char*转为CString
CString strUtf(cCharUtf);
length = strUtf.GetLength(); // length = 10;
CString strUnicode = UTF82WCS(cCharUtf);
length = strUnicode.GetLength(); // length = 8;
这里在中文 “中国”和“你好”之间加了英文的标点符号,显示正常。
实例三:
int length;
wchar_t* wCharUnicode = L"中国,你好abc";
length = wcslen(wCharUnicode); // length = 8;
char* cCharUtf = UnicodeToUtf8(wCharUnicode);
length = strlen(cCharUtf); // length = 18;
// 将UTF格式的char*转为CString
CString strUtf(cCharUtf);
length = strUtf.GetLength(); // length = 10;
CString strUnicode = UTF82WCS(cCharUtf);
length = strUnicode.GetLength(); // length = 8;
这里在中文 “中国”和“你好”之间加了中文的标点符号,cCharUtf 在VS中看不到值,但是可以转成CString查看其值,结果正确。
尾
我们从三个不同实例的测试结果中看到一个中文字符或者中文标点符号,占了三个字节(有资料显示 UTF-8编码:采用变长字节 ,1 :ASCII, 2: 希腊字母, 3: 汉字, 4: 中日韩超大字符集,这里常用汉字占用3个,不常用的汉字占用4个字节 ),中文标点符号与英文标点符号差了两个字节,这里要特别注意,而英文字符在UTF-8下都为一个字节。
同时我们可以看到用CString 类型变量来分别接收Unicode和UTF-8编码的字符,这里我们看到长度不一致(这里特值字符长度,并不是字符所占字节数),虽然我们看到UTF-8编码比Unicode编码要长,但是并不是绝对的,因为UTF-8在存储不同字符时所占的内存大小不一样,就比如存储ASCII码 就只需要一个字节,而Unicode需要两个字节,关于编码问题还是挺复杂的,而正是Unicode储存ASCII也需要两个字节,这里就出现了UTF-8、UTF-16、UTF-32等不同的字符编码格式,至于为什么会出现这么多的编码格式,那也是因为每种编码格式保存字符的空间大小不一致,就比如UTF-8保存一个英文字母只需要一个字节,而Unicode需要两个字节,但是保存一个中文字符,UTF-8需要三个字节,而Unicode则需要两个字节。
UTF全称为unicode transformation format,其实说白了,UTF-8就是Unicode的实现方式之一, ,UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
网上也有好多关于字符问题的资料,但是说法不一,所以还是要经过多方验证,这里需要注意一下。
http://blog.csdn.net/goforwardtostep/article/details/53207804
Unicode与UTF8相互转化(使用MultiByteToWideChar)的更多相关文章
- Linux 平台和 Windows平台下 Unicode与UTF-8互转
Windows: unsigned char * make_utf8_string(const wchar_t *unicode) { , index = , out_index = ; unsign ...
- 使用 WideCharToMultiByte Unicode 与 UTF-8互转
1.简述 最近在发送网络请求时遇到了中文字符乱码的问题,在代码中调试字符正常,用抓包工具抓的包中文字符显示正常,就是发送到服务器就显示乱码了,那就要将客户端和服务器设置统一的编码(UTF-8),而我们 ...
- [C/C++]_[Unicode转Utf8,Ansi转Unicode,Ansi文件转Utf8文件]
http://blog.csdn.net/infoworld/article/details/15337665 场景: 1.也就只有windows需要那么麻烦,还搞一个ANSI编码.学学mac os ...
- Ansi、Unicode、UTF8字符串之间的转换和写入文本文件
转载请注明出处http://www.cppblog.com/greatws/archive/2008/08/31/60546.html 最近有人问我关于这个的问题,就此写一篇blog Ansi字符串我 ...
- Unicode 和 UTF-8 有何区别?
Unicode符号范围 (一个字符两个字节) | UTF-8编码方式 (十六进制) | (二进制) —————————————————————– 这儿有四个字节从-----00 00 ...
- Unicode和UTF-8的关系
Unicode和UTF-8都是表示编码,这个我一直都知道,但是这两个实际上是干什么用的,到底是怎么编码的,为什么有了Unicode还要UTF-8,它们之间有什么联系又有什么区别呢?这个问题一直困扰着我 ...
- 字符编码笔记:ASCII,Unicode和UTF-8
很久很久以前,有一群人,他们决定用8个可以开合的晶体管来组合成不同的状态,以表示世界上的万物.他们看到8个开关状态是好的,于是他们把这称为"字节". 再后来,他们又做了一些可以处理 ...
- 字符编码笔记:ASCII,Unicode和UTF-8 转
本文出处 http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html 只是为了记录一下省得要去搜. 今天中午,我突然想搞清楚 ...
- [转]字符编码笔记:ASCII,Unicode和UTF-8
转自:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html 作者: 阮一峰 日期: 2007年10月28日 今天中午, ...
随机推荐
- js:语言精髓笔记9--函数式语言特征
形式化运算系统的研究: 图灵:提出图灵机形式系统,通过0,1运算系统来解决复杂问题: 冯诺依曼:提出了冯诺依曼体系:即通过修改内存反映运算结果: 阿隆左.丘奇:提出新的运算范型Lambda演算,计算机 ...
- bug 调试了一个下午外加半个晚上的bug
public void queryTaskResult2() throws Exception { HttpServletRequest request = ServletActionContext. ...
- BZOJ3829 : [Poi2014]FarmCraft
d[x]表示走完x的子树并回到x所需的时间 f[x]表示从走到x开始计时,x子树中最晚的点安装完的最早时间 d[x]=sum(d[i]+2),i是x的孩子 f[x]的计算比较复杂: 考虑将x的各棵子树 ...
- Session赋值(备注)
Session赋值也是在后台赋,不是在前台赋 追问 不好意思 那还真能在AJAX中赋值 我已经解决了 加一个接口IRequiresSessionState 就OK 提问者评价 太感谢了,真心有用
- ECMAScript继承
继承的定义 ECMAScript 实现继承可以从父类入手,所有开发者定义的类都可作为父类,出于安全考虑,本地类和宿主类不能作为父类,因为容易收到恶意攻击 创建只是用于给子类提供通用函数的父类被看作抽象 ...
- 安装win7 ubuntu双系统
http://www.cnblogs.com/shengansong/archive/2011/10/23/2221716.html http://www.cnblogs.com/shenganson ...
- NSThread
每个iOS应用程序都有个专门用来更新显示UI界面.处理用户的触摸事件的主线程,因此不能将其他太耗时的操作放在主线程中执行,不然会造成主线程堵塞(出现卡机现象),带来极坏的用户体验.一般的解决方案就是将 ...
- FlyCapture2 VS2010 Configuration
Add in the system Path: C:\Program Files (x86)\Point Grey Research\FlyCapture2\bin Project->Proje ...
- order by id asc得出的排序是什么原理
我们要用order by id asc得出的排序应该是,4,好了原理就这么简. sql实现方法,代码如下: : 代码如下: $sql ="Select 字段 from 表名 where id ...
- 释放用完的Excel COM组件
How to Open; SaveAs; then Close an Excel 2013 (macro-enabled) workbook from PowerShell4 1. (http:/ ...