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 类型变量来分别接收UnicodeUTF-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

时间: 2024-12-18 12:00:53

Unicode与UTF8相互转化(使用MultiByteToWideChar)的相关文章

几个多字节和UNICODE及UTF-8之间相互转化的函数

做vc++开发免不了多字节UNICODE.UTF-8转来转去,下面贴出我写的几个字符转化函数 1. TCHAR  和CHAR转化, TCHAR 对应UNICODE和多字节下分别是WCHAR 和CHAR 函数如下: 需要注意*dest是new出来的需要释放 //char 字符串转化为tchar字符串 void C2T(TCHAR** dest, const char* src) { #ifdef _UNICODE if (src == NULL) { return ; } size_t alen

python 字符串编码 str和unicode 区别以及相互转化 decode('utf-8') encode('utf-8')

python 字符串编码 str和unicode 区别以及相互转化 decode('utf-8') encode('utf-8') 原文地址:https://www.cnblogs.com/zhaoyingjie/p/9133020.html

PHP实现Unicode和Utf-8互相转换

  一. 编码原理及实现 unicode编码是实现utf-8与gb系列编码(gb2312.gbk.gb18030)转换的基础,虽然我们也可以直接做一个utf-8到这些编码 的对照表,但很少有人会这么做,因为utf-8的可变编码具有不确定性,因此一般情况使用都是unicode与gb编码的对照 表,unicode(UCS-2)实际上是utf-8的基础编码,utf-8只是它的一种实现而已,两者存在下面的对应关系: Unicode符号范围           | UTF-8编码方式 u0000 0000

Ansi UNICODE,GBK,UTF-8区别

http://my.oschina.net/saintzbs/blog/165034 http://my.oschina.net/saintzbs/blog/165034 http://www.cnblogs.com/cy163/archive/2007/05/31/766886.html 1:可以借助于文本编辑页面和Compare进行理解.      Unicode.utf-8.GB2312等,但是在windows命令行里敲notepad进入文本编辑页面.保存时需要选择编码方式,但是不存在GB

c/c++ 中文字符串转Unicode和UTF8

1. 描述 在windows上做系统编程,少不了会遇到处理中文字符串的问题.而大多时候中文汉字都是以多字节编码的方式展现的.为了实现更好的兼容性或一些特殊的需求,(比如在网页上显示.)常需要将其转换成unicode或者utf8的格式. 2. 代码示例 2.1 中文字符串转Unicode /************************************************************************ *int CN2Unicode(char *input,wcha

Visual C++ unicode and utf8 转换

ATL宏: USES_CONVERSION; W2A A2W CString StringUtil::UTF8_to_UNICODE(const char *utf8_string, int length){    int wcsLen = ::MultiByteToWideChar(CP_UTF8, NULL, utf8_string, length, NULL, 0);       wchar_t* wszString = new wchar_t[wcsLen + 1];    ::Mult

c++ ANSI、UNICODE、UTF8互转

static std::wstring MBytesToWString(const char* lpcszString);    static std::string WStringToMBytes(const wchar_t* lpwcszWString);    static std::wstring UTF8ToWString(const char* lpcszString);    static std::string WStringToUTF8(const wchar_t* lpwcs

字符编码笔记:ASCII,Unicode和UTF-8【转载】

最近买了部安卓的手机,google nexus5 系统是安卓4.4.2. 刚到手就发现链接wifi有问题,一直在获取ip(obtaining ip...)和验证.试过恢复出厂 重启 各种都不管用,只有设置静态ip才可以,但是不能一直这样子呀!! 查了下路由器,路由器已经分配了地址.所以最大可能就是安卓手机上拿到这个地址没有成功写入配置文件,为什么没有写入呢,就是权限的问题了,不明白为什么google会出现这个错误. 因为不熟悉安卓系统,所以查了好几天,终于在一个外国网站上发现了下面这个解决办法,

<转>字符编码笔记:ASCII,Unicode和UTF-8

本文转自:http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html 今天中午,我突然想搞清楚Unicode和UTF-8之间的关系,于是就开始在网上查资料. 结果,这个问题比我想象的复杂,从午饭后一直看到晚上9点,才算初步搞清楚. 下面就是我的笔记,主要用来整理自己的思路.但是,我尽量试图写得通俗易懂,希望能对其他朋友有用.毕竟,字符编码是计算机技术的基石,想要熟练使用计算机,就必须懂得一点字符编码的知识. 1. ASC