宽字符集操作函数_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正则表达式匹配和替换的操作指南

《Python正则表达式匹配和替换的操作指南》正则表达式是处理文本的强大工具,Python通过re模块提供了完整的正则表达式功能,本文将通过代码示例详细介绍Python中的正则匹配和替换操作,需要的朋... 目录基础语法导入re模块基本元字符常用匹配方法1. re.match() - 从字符串开头匹配2.

C++统计函数执行时间的最佳实践

《C++统计函数执行时间的最佳实践》在软件开发过程中,性能分析是优化程序的重要环节,了解函数的执行时间分布对于识别性能瓶颈至关重要,本文将分享一个C++函数执行时间统计工具,希望对大家有所帮助... 目录前言工具特性核心设计1. 数据结构设计2. 单例模式管理器3. RAII自动计时使用方法基本用法高级用法

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

sysmain服务可以禁用吗? 电脑sysmain服务关闭后的影响与操作指南

《sysmain服务可以禁用吗?电脑sysmain服务关闭后的影响与操作指南》在Windows系统中,SysMain服务(原名Superfetch)作为一个旨在提升系统性能的关键组件,一直备受用户关... 在使用 Windows 系统时,有时候真有点像在「开盲盒」。全新安装系统后的「默认设置」,往往并不尽编

Python自动化处理PDF文档的操作完整指南

《Python自动化处理PDF文档的操作完整指南》在办公自动化中,PDF文档处理是一项常见需求,本文将介绍如何使用Python实现PDF文档的自动化处理,感兴趣的小伙伴可以跟随小编一起学习一下... 目录使用pymupdf读写PDF文件基本概念安装pymupdf提取文本内容提取图像添加水印使用pdfplum

GO语言中函数命名返回值的使用

《GO语言中函数命名返回值的使用》在Go语言中,函数可以为其返回值指定名称,这被称为命名返回值或命名返回参数,这种特性可以使代码更清晰,特别是在返回多个值时,感兴趣的可以了解一下... 目录基本语法函数命名返回特点代码示例命名特点基本语法func functionName(parameters) (nam

Python从Word文档中提取图片并生成PPT的操作代码

《Python从Word文档中提取图片并生成PPT的操作代码》在日常办公场景中,我们经常需要从Word文档中提取图片,并将这些图片整理到PowerPoint幻灯片中,手动完成这一任务既耗时又容易出错,... 目录引言背景与需求解决方案概述代码解析代码核心逻辑说明总结引言在日常办公场景中,我们经常需要从 W

Python Counter 函数使用案例

《PythonCounter函数使用案例》Counter是collections模块中的一个类,专门用于对可迭代对象中的元素进行计数,接下来通过本文给大家介绍PythonCounter函数使用案例... 目录一、Counter函数概述二、基本使用案例(一)列表元素计数(二)字符串字符计数(三)元组计数三、C

使用Python的requests库来发送HTTP请求的操作指南

《使用Python的requests库来发送HTTP请求的操作指南》使用Python的requests库发送HTTP请求是非常简单和直观的,requests库提供了丰富的API,可以发送各种类型的HT... 目录前言1. 安装 requests 库2. 发送 GET 请求3. 发送 POST 请求4. 发送

Python中的filter() 函数的工作原理及应用技巧

《Python中的filter()函数的工作原理及应用技巧》Python的filter()函数用于筛选序列元素,返回迭代器,适合函数式编程,相比列表推导式,内存更优,尤其适用于大数据集,结合lamb... 目录前言一、基本概念基本语法二、使用方式1. 使用 lambda 函数2. 使用普通函数3. 使用 N