学习笔记:sprintf做编码转换
2016-04-25 18:21
567 查看
#include "stdafx.h" #include <clocale> #include <errno.h> #include <string.h> void test_1(){ std::setlocale(LC_ALL,"C"); char buff[512]={0}; //sprintf函数的%s参数,是小s,意思是接收小char的字符串 //对于任意字符,原封不动的拷贝到目标缓冲区去。 //这意味着它不具有做字符编码的转换的功能。locale设置对它毫无影响。 char str[]={0x5F,0x20,'|',0xD5,0xC5,0x00}; sprintf(buff,"%s",str); if (errno){ perror("failed reason:"); errno=0; } //当sprintf函数是%S参数时,是大S,意味着接收大号的char字符串(wchar_t字符串) //对于wchar_t字符,必须是unicode编码,否则会出错。 //本例中,混入了一个GBK编码0xD5C5, 如果它在unicode范围内,很可能会造成函数失败。 wchar_t StrErr[]={0x5F20, L'|', 0xD5C5, 0x0000}; sprintf(buff,"%S",StrErr); if (errno){ perror("failed reason:"); errno=0; } //为了排除错误,只保留unicode编码"张"(u5F20) //但是仍旧函数出错误,原因是需要设置从unicode转ansi的一个重要参数:本地的语言 wchar_t StrOK[]={0x5F20, L'|', 0x0000}; sprintf(buff,"%S",StrOK); if (errno){ perror("failed reason:"); errno=0; } //设置好本地的CTYPE,一般是中文GBK。除非控制面板->区域设置不是中国(简体,大陆) std::setlocale(LC_CTYPE,""); sprintf(buff,"%S",StrOK); //一般会成功的。 if (errno){ perror("failed reason:"); errno=0; } } #include <windows.h> void test_2(){ //因为知道宽字节类的函数可能依赖现场,先设置成chs现场 //然后继续做测试 std::setlocale(LC_ALL,""); wchar_t wbuff[512]={0}; //..W函数,如果是小s,将理解str为wchar数组的首地址。 //实际上str数组被理解成: wchar_t数组[0x205F,0xD57C, 0x00C5] //这个数组没有字符串结束符,将会造成严重后果。 char str[]={0x5F,0x20,'|',0xD5,0xC5,0x00}; wsprintfW( wbuff, L"%s", str ); if (errno){ perror("failed reason:"); errno=0; } //大S,匹配char数组是正确的。 //但是要求str里面必须是ansi本地编码。本函数可以将ansi本地编码转为unicode //由于{0x5F,0x20}组合序列不是GBK编码,所以函数认为是'_'和' '。 wsprintfW( wbuff, L"%S", str ); if (errno){ perror("failed reason:"); errno=0; } //小s接收wchar_t数组,将数组原封不动拷贝到目标中 wchar_t Str[]={0x5F20, L'|',0xD5C5 ,0x0000}; wsprintfW( wbuff, L"%s", Str ); if (errno){ perror("failed reason:"); errno=0; } //大S接收char数组,所以把Str认为是如下数组: //char[ 0x20, 0x5F, 0x7C, 0x00, 0xC5, 0xD5, 0x00, 0x00 ] //字符串的头三个字符都是ascii字符,在第4个字符截止。 //没有一对组合是GBK编码 wsprintfW( wbuff, L"%S", Str ); if (errno){ perror("failed reason:"); errno=0; } //用wsprintfW函数时,%S 对应 char[] , %s 对应 wchar_t[] //用wsprintfA函数时,%S 对应 wchar_t[] , %s 对应 char[] //windows下,根据宏定义是否是unicode,封装了上述两个函数 //wsprintf()或者是wsprintfW,或者是wsprintfA。 TCHAR buff[512]; //宏定义封装的 TCHAR* str2=_T("张"); //宏定义封装的 wsprintf(buff, _T("%s"), str2 ); //不管是A还是W,小s,总能对应正确 if (errno){ perror("failed reason:"); errno=0; } wsprintf(buff, _T("%S"), str2 ); //但是S,总是对应错误的参数。所以微软提供的wsprintf宏不是很合理 if (errno){ perror("failed reason:"); errno=0; } } #include <wchar.h> void test_3(){ wchar_t buffer [100]; int cx; std::setlocale(LC_ALL,""); char *str = "张"; cx = swprintf ( buffer, 100, L"%S", str ); if (errno){ perror("failed reason:"); errno=0; } wchar_t *Str = L"张"; cx = swprintf ( buffer, 100, L"%s", Str ); if (errno){ perror("failed reason:"); errno=0; } //实际上,标准C函数 // sprintf %s 对应 char , %S 对应 wchar_t // swprintf %s 对应 wchar_t, %S 对应 char } int main() { test_3(); system("pause"); return 0; }
相关文章推荐
- 追加window.onload函数
- 【Netty4 简单项目实践】一、长连接服务通用框架原型
- Java反射使用实例(http实体类转换)
- RecyclerView和CardView的使用以及注意
- scala入门3
- hdu 3507 Print Article(斜率优化DP)
- 也许,DOM 不是答案(手机APP页面开发的思考)
- 我的第一篇博客
- linux bash shell之declare
- sds
- HDU 5620 KK's Steel(思维题)
- STL学习_SGI空间配置器
- LBS(定位)的使用
- Java中Vector和ArrayList的区别
- redis sentinel(哨兵)模式
- Java多线程系列--“基础篇”03之 Thread中start()和run()的区别
- Android开发本地及网络Mp3音乐播放器(七)循环模式与专辑倒影
- Android开发本地及网络Mp3音乐播放器(七)循环模式与专辑倒影
- svn ignore 的用法(忽略文件及目录)
- UVA 10341 Solve It (二分)