学习笔记:sprintf做编码转换

来源:互联网 发布:中文编程从入门到精通 编辑:程序博客网 时间:2024/06/15 15:49
#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;} 

0 0
原创粉丝点击