utf |
您所在的位置:网站首页 › gbk改成utf8 › utf |
今天在windows控制台上打印utf-8字符时出现了乱码,然后就折腾了一下发现在简体中文版上的windows默认的代码页是936(gbk编码),在控制台上输入chcp 65001解决之(65001是UTF-8代码页编号),但是我这么爱钻研(瞎折腾)怎么可能就这么完事了呢,就尝试了下用C语言实现utf-8转化成gbk编码(还顺便学习了下几种编码),下面是解决方法。 嗯。。还有我学习时看的一个资料,介绍编码知识的 http://www.ruanyifeng.com/blog/2007/10/ascii_unicode_and_utf-8.html 解决方法 1.使用代码更改活动代码页system("chcp 65001"); 也可以使用windows的一个API(设置输出代码页),效果一样 SetConsoleOutputCP(65001); 还有另外一个API是SetConsoleCP(),这个API设置的是输入代码页,在输出时并不起作用 C语言标准里面还提供了一个函数来设置代码页Setlocale(),不过没有测试过 2.将utf-8转换成gbk编码原理是利用windows的两个API,将UTF-8转成unicode编码,再转成gbk编码 下面是对两个函数的介绍 函数原型int MultiByteToWideChar( UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cchMultiByte, LPWSTR lpWideCharStr, int cchWideChar); 函数功能该函数映射一个字符串到一个宽字符(unicode)的字符串。由该函数映射的字符串没必要是多字节字符组。 参数CodePage:指定执行转换的代码页,这个参数可以为系统已安装或有效的任何代码页所给定的值。我们用到的是下面两个值(当然你也可以指定别的值): CP_ACP:ANSI代码页(简体中文Windows操作系统中,ANSI 编码代表 GBK 编码) CP_UTF8:使用UTF-8转换 dwFlags: 指定如何处理没有转换的字符,但不设此参数函数会运行的更快一些,我都是把它设为0。 可设的值如下表所示: WC_NO_BEST_FIT_CHARS 把不能直接转换成相应多字节字符的Unicode字符转换成lpDefaultChar指定的默认字符。也就是说,如果把Unicode转换成多字节字符,然后再转换回来,你并不一定得到相同的Unicode字符,因为这期间可能使用了默认字符。此选项可以单独使用,也可以和其他选项一起使用。 WC_COMPOSITECHECK 把合成字符转换成预制的字符。它可以与后三个选项中的任何一个组合使用,如果没有与他们中的任何一个组合,则与选项WC_SEPCHARS相同。 WC_ERR_INVALID_CHARS 此选项会致使函数遇到无效字符时失败返回,并且GetLastError会返回错误码ERROR_NO_UNICODE_TRANSLATION。否则函数会自动丢弃非法字符。此选项只能用于UTF8。 WC_DISCARDNS 转换时丢弃不占空间的字符,与WC_COMPOSITECHECK 一起使用 WC_SEPCHARS 转换时产生单独的字符,此是默认转换选项,WC_COMPOSITECHECK一起使用 WC_DEFAULTCHAR 转换时使用默认字符代替例外的字符,(最常见的如’?’),与WC_COMPOSITECHECK一起使用。 对于下列代码页,dwFlags必须为0,否则函数返回错误码ERROR_INVALID_FLAGS。 50220 50221 50222 50225 50227 50229 52936 54936 57002到57011 65000(UTF7) 42(Symbol) 对于UTF8,dwFlags必须为0或WC_ERR_INVALID_CHARS,否则函数都将失败返回并设置错误码ERROR_INVALID_FLAGS,你可以调用GetLastError获得。 lpMultiByteStr:指向将被转换字符串的字符。 cchMultiByte:指定由参数lpMultiByteStr指向的字符串中字节的个数。如果这个值为-1,字符串将被设定为以NULL为结束符的字符串,并且自动计算长度。 lpWideCharStr:指向接收被转换字符串的缓冲区。 cchWideChar:指定由参数lpWideCharStr指向的缓冲区的字节个数。若此值为零,函数返回缓冲区所必需的宽字符数,在这种情况下,lpWideCharStr中的缓冲区不被使用。 返回值:如果函数运行成功,并且cchWideChar不为零,返回值是由lpWideCharStr指向的缓冲区中写入的宽字符数;如果函数运行成功,并且cchMultiByte为零,返回值是接收到待转换字符串的缓冲区所需求的宽字符数大小。如果函数运行失败,返回值为零。 函数原型int WideCharToMultiByte( UINT CodePage, DWORD dwFlags, LPCWSTR lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar); 函数功能此函数把宽字符串转换成指定的新的字符串,如ANSI,UTF8等,新字符串不必是多字节字符集。 参数lpWideCharStr : 待转换的宽字符串。 cchWideChar : 待转换宽字符串的长度,-1表示转换到字符串结尾。 lpMultiByteStr : 接收转换后输出新串的缓冲区。 cbMultiByte :输出缓冲区大小,如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不使用lpMultiByteStr。 lpDefaultChar : 指向字符的指针, 在指定编码里找不到相应字符时使用此字符作为默认字符代替。如果为NULL则使用系统默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。 lpUsedDefaultChar :开关变量的指针,用以表明是否使用过默认字符。对于要求此参数为NULL的dwFlags而使用此参数,函数将失败返回并设置错误码ERROR_INVALID_PARAMETER。lpDefaultChar和lpUsedDefaultChar都设为NULL,函数会更快一些。 返回值 :如果函数成功,且cbMultiByte非0,返回写入lpMultiByteStr的字节数(包括字符串结尾的null);cbMultiByte为0,则返回转换所需字节数。函数失败,返回0。 下面是简单的函数实现 void utf8ToGbk(char *utf8String, char *gbkString) { wchar_t *unicodeStr = NULL; int nRetLen = 0; nRetLen = MultiByteToWideChar(CP_UTF8, 0, utf8String, -1, NULL, 0); //求需求的宽字符数大小 unicodeStr = (wchar_t *)malloc(nRetLen * sizeof(wchar_t)); nRetLen = MultiByteToWideChar(CP_UTF8, 0, utf8String, -1, unicodeStr, nRetLen); //将utf-8编码转换成unicode编码 nRetLen = WideCharToMultiByte(CP_ACP, 0, unicodeStr, -1, NULL, 0, NULL, 0); //求转换所需字节数 nRetLen = WideCharToMultiByte(CP_ACP, 0, unicodeStr, -1, gbkString, nRetLen, NULL, 0); //unicode编码转换成gbk编码 free(unicodeStr); } 第三篇文章哈哈哈哈 人生是一场规模庞大的摸彩游戏,只有中奖的彩票展现在我们眼前。——《纸牌的秘密》 给我点十个赞我就买杯可乐庆祝下 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |