宽字符集操作函数_wchar_t 宽字符集 研究 和COM的 BSTR VARIANT

2024-02-17 04:32

本文主要是介绍宽字符集操作函数_wchar_t 宽字符集 研究 和COM的 BSTR VARIANT,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

http://smycll.blog.hexun.com/80156767_d.html

 

宽字符集操作函数_wchar_t 宽字符集 研究 和COM的 BSTR VARIANT

 

wchar_t 是和 char 平等的地位,即 wchar_t 并非 typedef出来的,是原生的变量。

简单的说,它拥有两个字节,和short 占用空间一样。

比如:

字符串 "我们\n"

ANSI 的十六进制为:ce d2 c3 c7 0A 00

6个字节,其中包括字符串最后的\0

Unicode十六进制为:11 62 EC 4E 0A 00 00 00

8个字节,所有的字符 全部是2个字节,即使字母  数字 都是,当然换行\n  也是0A 00 了。

一般 程序中字符串 前面加个  L"" 就表示 是Unicode 字符串了。

windows下有一个 宏 _T("") 和上面的一样。

1.第一个简单的问题,如何打印出来 Unicode?

2个字节,可以按照 数字打印,但是如果要按照字符 打印,用普通的printf 是不行了。

可以使用wprintf打印,也就是 普通的 printf前面加一个 Wide的 W。类似的函数都是,比如 wsprintf。

复制代码
    char* lpszText = "我们\r\n";//ANSI:ce d2 c3 c7//Unicode:11 62 EC 4E//回车 \r 0D  \n 0Aprintf("char * text: %s 0x%08x 0x%08x \nANSI编码是   :", lpszText, lpszText, *lpszText );print_hex_to_file(stdout,(const uint8_t *)lpszText,strlen(lpszText)+1,16);//此函数自己编写的BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText);wprintf(L"BSTR text: %s 0x%08x 0x%08x \nUniCode编码是:", bstrText, bstrText, *bstrText);print_hex_to_file(stdout,(const uint8_t *)bstrText,wcslen(bstrText)*2+2,16);
复制代码

的结果为:

复制代码
char * text: 我们 
0x013fbd80 0xffffffceANSI编码是 :0x ce d2 c3 c7 0d 0a 00BSTR text: 我们
0x007be5b4 0x00006211UniCode编码是:0x 11 62 ec 4e 0d 00 0a 00 00 00
复制代码

对了,开始我用wprintf始终无法打印中文,后来 添加了下面的两句 才可以了。

    #include <locale.h>setlocale( LC_CTYPE, "chs" );

源码的编码 是 ANSI 或  UniCode 对结果 都没有什么影响。

对了 如果要打印单个 wchar_t 怎么打印呢?上面都是指针,都是字符串,那好好办。单个。。。

    setlocale( LC_CTYPE, "chs" );WCHAR wstr1;wchar_t wstr2;wstr1=L'';wstr2=L'';wprintf(L"我们 在宽字符集(%c,%c) 的每个大小为:%d 字节\n",wstr1,wstr2,sizeof(wstr1));

赋值的时候 始终记住 L  ,结果正常。

我们 在宽字符集(我,们) 的每个大小为:2 字节

如果你将 '我' 赋值给 一个 char 类型,那么 你只能得到 '我' ce d2  的 前一个 字节。打印出来 肯定 就是乱码  ? 了。

复制代码
char ss;
ss='';
printf("ss=%c\n",ss);结果是:
ss=? 
复制代码

并且 ?  后面是没有换行的,因为 \n 已经和 %c 融合 为 ?  了。。反正 ce 打印出来 或许 很诡异的。

2.第二个简单的问题,如何 与 char 类型 互相转换

复制代码
int ConvertStringToBSTRDemo()
{char* lpszText = "Test";printf("char * text: %s\n", lpszText);BSTR bstrText = _com_util::ConvertStringToBSTR(lpszText);wprintf(L"BSTR text: %s\n", bstrText);::SysFreeString(bstrText);return 0;
};
int ConvertBSTRToStringDemo()
{BSTR bstrText = ::SysAllocString(L"Test");wprintf(L"BSTR text: %s\n", bstrText);char* lpszText2 = _com_util::ConvertBSTRToString(bstrText);printf("char * text: %s\n", lpszText2);::SysFreeString(bstrText);
    delete[] lpszText2;return 0;
};
复制代码

这个全局函数 SysFreeString() 发现 不加 貌似 也没有内存泄漏?(VLD检测)

我靠,我知道了,可能是VLD没有重载COM里的内存分配释放,所以 还是 去掉 SysFreeString前的注释。

经过实验 循环10 000 000次,会发生 300MB左右的内存泄漏。但是VLD确实无法检测。所以 千万得小心了!

COM编程里的 BSTR其实就是wchar_t* 类型,有BSTR的地方就是分配了指针的,一定要自己释放内存的!

BSTR和String(char *) 的转换,其实就是 wchar_t* 和 char * 的转换了。这是COM的方法

还可以使用stdlib里的方法:

wcstombs 和 mbstowcs  wcs应该就是WideCString ,但是 mbs 怎么就表示 ansi普通的字符编码 我就不知道缩写了

复制代码
    wchar_t   ws[10]; //sizeof(ws)=20字节wsprintf(ws,L"我们");char cs[50];sprintf(cs,"");//清除数据 与初始化//wchar_t * 转化为 char *int ret=0;printf("wcstombs前:       cs=%4s ws=%%S=%S\n",cs,ws);ret=wcstombs(cs,ws,sizeof(ws));printf("wcstombs后: ret=%d,cs=%4s ws=%%S=%S\n",ret,cs,ws);wsprintf(ws,L"");//清除数据 与初始化//char * 转化为 wchar_t *wprintf(L"mbstowcs前:       ws=%4s cs=%%S=%S\n",ws,(cs));ret=mbstowcs(ws,cs,sizeof(ws)*2);wprintf(L"mbstowcs后: ret=%d,ws=%2s cs=%%S=%S\n",ret,ws,(cs));
复制代码

运行结果

wcstombs前:       cs=     ws=%S=我们
wcstombs后: ret=4,cs=我们 ws=%S=我们
mbstowcs前:       ws=     cs=%S=我们
mbstowcs后: ret=2,ws=我们 cs=%S=我们

windows下也有另外的相同意思的API

//MultiByteToWideChar

最后 加上 我喜欢的 print_hex_to_file函数

复制代码
void print_hex_to_file(FILE*fp,const uint8_t *array, int count/*aray的大小*/,int lineCount/*默认应该是16*/)
{int i;fprintf(fp,"0x ");for(i = 0; i < count; ){fprintf(fp,"%02x ", array[i]);i++;if ( !(i % lineCount) && i<count){fprintf (fp,"\n0x ");}}fprintf(fp,"\n");
};
复制代码

转载请注明出处:http://www.cnblogs.com/ayanmw 多谢

------------------------------------------------------------------------------------------------

一定要专业!本博客定位于ArcGIS开发,C语言,C++语言,Java语言,Android开发和少量的Web开发,之前是做Web开发的,其实就是ASP维护,发现EasyASP这个好框架,对前端后端数据库 都很感觉亲切啊。.


-------------------------


字符分类: 宽字符函数普通C函数描述

iswalnum()      isalnum() 测试字符是否为数字或字母

iswalpha()      isalpha() 测试字符是否是字母

iswcntrl()      iscntrl() 测试字符是否是控制符

iswdigit()      isdigit() 测试字符是否为数字

iswgraph()      isgraph() 测试字符是否是可见字符

iswlower()      islower() 测试字符是否是小写字符

iswprint()      isprint() 测试字符是否是可打印字符

iswpunct()      ispunct() 测试字符是否是标点符号

iswspace()      isspace() 测试字符是否是空白符号

iswupper()      isupper() 测试字符是否是大写字符

iswxdigit()     isxdigit()测试字符是否是十六进制的数字

大小写转换:

宽字符函数     普通C函数描述

towlower()      tolower() 把字符转换为小写

towupper()      toupper() 把字符转换为大写

字符比较:      宽字符函数普通C函数描述

wcscoll()      strcoll() 比较字符串

日期和时间转换:

宽字符函数描述

strftime()      根据指定的字符串格式和locale设置格式化日期和时间

wcsftime()      根据指定的字符串格式和locale设置格式化日期和时间, 并返回宽字符串

strptime()      根据指定格式把字符串转换为时间值, 是strftime的反过程

打印和扫描字符串:

宽字符函数描述

fprintf()/fwprintf()      使用vararg参量的格式化输出

fscanf()/fwscanf()          格式化读入

printf()              使用vararg参量的格式化输出到标准输出

scanf()              从标准输入的格式化读入

sprintf()/swprintf()      根据vararg参量表格式化成字符串

sscanf()              以字符串作格式化读入

vfprintf()/vfwprintf()      使用stdarg参量表格式化输出到文件

vprintf()              使用stdarg参量表格式化输出到标准输出

vsprintf()/vswprintf()      格式化stdarg参量表并写到字符串

数字转换:

宽字符函数     普通C函数描述

wcstod()        strtod()   把宽字符的初始部分转换为双精度浮点数

wcstol()        strtol()   把宽字符的初始部分转换为长整数

wcstoul()       strtoul() 把宽字符的初始部分转换为无符号长整数

多字节字符和宽字符转换及操作:

宽字符函数描述

mblen()          根据locale的设置确定字符的字节数

mbstowcs()          把多字节字符串转换为宽字符串

mbtowc()/btowc()     把多字节字符转换为宽字符

wcstombs()          把宽字符串转换为多字节字符串

wctomb()/wctob()      把宽字符转换为多字节字符


 

 

 

这篇关于宽字符集操作函数_wchar_t 宽字符集 研究 和COM的 BSTR VARIANT的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/716679

相关文章

python panda库从基础到高级操作分析

《pythonpanda库从基础到高级操作分析》本文介绍了Pandas库的核心功能,包括处理结构化数据的Series和DataFrame数据结构,数据读取、清洗、分组聚合、合并、时间序列分析及大数据... 目录1. Pandas 概述2. 基本操作:数据读取与查看3. 索引操作:精准定位数据4. Group

MySQL常用字符串函数示例和场景介绍

《MySQL常用字符串函数示例和场景介绍》MySQL提供了丰富的字符串函数帮助我们高效地对字符串进行处理、转换和分析,本文我将全面且深入地介绍MySQL常用的字符串函数,并结合具体示例和场景,帮你熟练... 目录一、字符串函数概述1.1 字符串函数的作用1.2 字符串函数分类二、字符串长度与统计函数2.1

Python操作PDF文档的主流库使用指南

《Python操作PDF文档的主流库使用指南》PDF因其跨平台、格式固定的特性成为文档交换的标准,然而,由于其复杂的内部结构,程序化操作PDF一直是个挑战,本文主要为大家整理了Python操作PD... 目录一、 基础操作1.PyPDF2 (及其继任者 pypdf)2.PyMuPDF / fitz3.Fre

python使用try函数详解

《python使用try函数详解》Pythontry语句用于异常处理,支持捕获特定/多种异常、else/final子句确保资源释放,结合with语句自动清理,可自定义异常及嵌套结构,灵活应对错误场景... 目录try 函数的基本语法捕获特定异常捕获多个异常使用 else 子句使用 finally 子句捕获所

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

MySQL 强制使用特定索引的操作

《MySQL强制使用特定索引的操作》MySQL可通过FORCEINDEX、USEINDEX等语法强制查询使用特定索引,但优化器可能不采纳,需结合EXPLAIN分析执行计划,避免性能下降,注意版本差异... 目录1. 使用FORCE INDEX语法2. 使用USE INDEX语法3. 使用IGNORE IND

Python使用openpyxl读取Excel的操作详解

《Python使用openpyxl读取Excel的操作详解》本文介绍了使用Python的openpyxl库进行Excel文件的创建、读写、数据操作、工作簿与工作表管理,包括创建工作簿、加载工作簿、操作... 目录1 概述1.1 图示1.2 安装第三方库2 工作簿 workbook2.1 创建:Workboo

postgresql使用UUID函数的方法

《postgresql使用UUID函数的方法》本文给大家介绍postgresql使用UUID函数的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录PostgreSQL有两种生成uuid的方法。可以先通过sql查看是否已安装扩展函数,和可以安装的扩展函数

MySQL字符串常用函数详解

《MySQL字符串常用函数详解》本文给大家介绍MySQL字符串常用函数,本文结合实例代码给大家介绍的非常详细,对大家学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录mysql字符串常用函数一、获取二、大小写转换三、拼接四、截取五、比较、反转、替换六、去空白、填充MySQL字符串常用函数一、

Ubuntu 24.04启用root图形登录的操作流程

《Ubuntu24.04启用root图形登录的操作流程》Ubuntu默认禁用root账户的图形与SSH登录,这是为了安全,但在某些场景你可能需要直接用root登录GNOME桌面,本文以Ubuntu2... 目录一、前言二、准备工作三、设置 root 密码四、启用图形界面 root 登录1. 修改 GDM 配