热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

有关UNICODE、ANSI字符集和相关字符串操作的总结(一)

对论坛中有关UNICODE、ANSI字符集和相关字符串操作的总结!先声明不是我的杰作。我这里只是总结了一部分,如果有错误请指出,同时欢迎大


对论坛中有关UNICODE、ANSI字符集和相关字符串操作的总结!先声明不是我的杰作。我这里只是总结了一部分,如果有错误请指出,同时欢迎大家参与进来!  

   

   

  Q   UNICODE字符串如何显示  

  A  

  如果程序定义了_UNICODE宏直接用  

  WCHAR   *str=L"unicodestring";  

  TextOut(0,0,str);  

  否则就需要转换类型  

  #include    

  WCHAR   *str=L"unicodestring";  

  bstr_t   str1=str;  

  TextOut(0,0,(char*)str1);  

   

  Q   如何实现ANSI和UNICODE的相互转换  

  A  

  将ANSI转换到Unicode  

  (1)通过L这个宏来实现,例如:   CLSIDFromProgID(   L"MAPI.Folder",&clsid);  

  (2)通过MultiByteToWideChar函数实现转换,例如:  

  char   *szProgID   =   "MAPI.Folder";  

  WCHAR   szWideProgID[128];  

  CLSID   clsid;  

  long   lLen   =   MultiByteToWideChar(CP_ACP,0,szProgID,strlen(szProgID),szWideProgID,sizeof(szWideProgID));  

  szWideProgID[lLen]   =   '\0';    

  (3)通过A2W宏来实现,例如:    

  USES_CONVERSION;    

  CLSIDFromProgID(   A2W(szProgID),&clsid);    

   

  将Unicode转换到ANSI  

  (1)使用WideCharToMultiByte,例如:  

  //   假设已经有了一个Unicode   串   wszSomeString...    

  char   szANSIString   [MAX_PATH];    

  WideCharToMultiByte   (   CP_ACP,   WC_COMPOSITECHECK,   wszSomeString,   -1,   szANSIString,   sizeof(szANSIString),   NULL,   NULL   );    

  (2)使用W2A宏来实现,例如:  

  USES_CONVERSION;  

  pTemp=W2A(wszSomeString);    

   

  注意在转换时可能存在的问题:  

  因为ANSI转UNICODE,如果使用A2W或MultiByteToWideChar(第一个参数是CP_ACP)的话,是根据系统默认的转码表,把转入的ANSI字符串看作Multi-Bytes字符串处理的,如果是中文(中文windows默认就是中文),一个大于0x87的byte可能和下一byte一起被看作一个汉字,然后根据汉字的Unicode编码转换为相同的Unicode汉字,如果找不到相应的编码,一般就用一个默认的字符来取代它(一般是问号“?”),由此看,如果随便把一段数据给他转,转化很复杂而且极可能不可逆,而且你加密过的ANSI码是相当混乱的有很多〉0x87的byte,转换就变得不可逆了。  

  建议自己直接就这样写:  

  CHAR   lpANSI[COUNT];  

  WCHAR   lpUnicode[COUNT];  

  int   i   =   0;    

  while(lpANSI[i]   !=   '\0'   )   {  

          lpUnicode[i]   =   (WCHAR)lpANSI[i];  

  }  

  lpUnicode[i]   =   L'\0';  

  然后按相同的方法转回来,因为对于0~0x87的ANSI字符串,对应的Unicode码就是相同的16位值,至于其他的,你的字符串反正加了密,没必要转换成显示出来是一样的字符,就按同样的方法处理了,其实如果中间的字符串不用显示或别的,直接reutrn   (LPWSTR)lpANSI;过去也可以,   反正接受的时候自己清楚就可以了。  

   

  Q   如何让程序支持UNICODE    

  A    

  NT系统的内核是unicode代码,通常vc分创建的工程默认都是ansi代码(可以兼容win9x),在nt下ansi程式在调用windows   API的时系统实际又进行了一次ansi到unicode的代码转化,如MoveWindowA实际上又调用MoveWindowW.如果以我们的程序不考虑win9x(早晚是明日黄花)的话,直接用unicode编译,那么程式的代码执行效率一定能增色不少.具体:  

  (0).在vc编译选项上,在vc7.0以上在工程的属性页中的“字符集”选上"使用   Unicode   字符集"即可,在vc6.0下可能麻烦一点,得先把vc运行库的unicode版本复制到vc路径下,一般都是和xxx.lib的ansi对应xxxU.lib,默认装vc时是不会装的,将工程属性  

  (0).1.改语言定义:  

  在project   settings的"C++"页中的"preprocessor   definitions"中改_MBCS为_UNICODE  

  (0).2.改入口函数:  

  在"link"页中的"project   Options"加入/entry:"wWinMainCRTStartup"即可.  

   

  (1)在代码上,处理字符中的多用TCHAR.H中的宏,如strcpy用_tcscpy代替,用TCHAR代char,  

  用TCHAR   m_mystr[]=_T("xxxx")代替   char   m_mystr[]="xxxx";  

  (2)注意调试UNICODE程序时,需要在安装时VC选择所有选项,否则会缺少动态库和相应的.lib文件  

   

  Q   如何取得一个既包含单字节字符又包含双字节字符的字符串的字符个数?  

  A  

  可以调用Microsoft   Visual   C++的运行期库包含函数_mbslen来操作多字节(既包括单字节也包括双字节)字符串。  

  调用strlen函数,无法真正了解字符串中究竟有多少字符,它只能告诉你到达结尾的0之前有多少个字节。  

   

  Q   如何对DBCS(双字节字符集)字符串进行操作?  

  A  

  函数   描述  

  PTSTR   CharNext   (   LPCTSTR   );   返回字符串中下一个字符的地址  

  PTSTR   CharPrev   (   LPCTSTR,   LPCTSTR   );   返回字符串中上一个字符的地址  

  BOOL   IsDBCSLeadByte(   BYTE   );   如果该字节是DBCS字符的第一个字节,则返回非0值  

   

  Q   为什么要使用Unicode?  

  A  

  (1)   可以很容易地在不同语言之间进行数据交换。  

  (2)   使你能够分配支持所有语言的单个二进制.exe文件或DLL文件。  

  (3)   提高应用程序的运行效率。  

  Windows   2000是使用Unicode从头进行开发的,如果调用任何一个Windows函数并给它传递一个ANSI字符串,那么系统首先要将字符串转换成Unicode,然后将Unicode字符串传递给操作系统。如果希望函数返回ANSI字符串,系统就会首先将Unicode字符串转换成ANSI字符串,然后将结果返回给你的应用程序。进行这些字符串的转换需要占用系统的时间和内存。通过从头开始用Unicode来开发应用程序,就能够使你的应用程序更加有效地运行。  

  Windows   CE   本身就是使用Unicode的一种操作系统,完全不支持ANSI   Windows函数  

  Windows   98   只支持ANSI,只能为ANSI开发应用程序。  

  Microsoft公司将COM从16位Windows转换成Win32时,公司决定需要字符串的所有COM接口方法都只能接受Unicode字符串。  

   

  Q   如何编写Unicode源代码?  

  A  

  Microsoft公司为Unicode设计了WindowsAPI,这样,可以尽量减少代码的影响。实际上,可以编写单个源代码文件,以便使用或者不使用Unicode来对它进行编译。只需要定义两个宏(UNICODE和_UNICODE),就可以修改然后重新编译该源文件。  

  _UNICODE宏用于C运行期头文件,而UNICODE宏则用于Windows头文件。当编译源代码模块时,通常必须同时定义这两个宏。  

   

  Q   Windows定义的Unicode数据类型有哪些?  

  A  

  数据类型   说明  

  WCHAR   Unicode字符  

  PWSTR   指向Unicode字符串的指针  

  PCWSTR   指向一个恒定的Unicode字符串的指针  

  对应的ANSI数据类型为CHAR,LPSTR和LPCSTR。  

  ANSI/Unicode通用数据类型为TCHAR,PTSTR,LPCTSTR。  

   

  Q   如何对Unicode进行操作?  

  A  

  字符集   特性   实例  

  ANSI   操作函数以str开头   strcpy  

  Unicode   操作函数以wcs开头   wcscpy  

  MBCS   操作函数以_mbs开头   _mbscpy  

  ANSI/Unicode   操作函数以_tcs开头   _tcscpy(C运行期库)  

  ANSI/Unicode   操作函数以lstr开头   lstrcpy(Windows函数)  

  所有新的和未过时的函数在Windows2000中都同时拥有ANSI和Unicode两个版本。ANSI版本函数结尾以A表示;Unicode版本函数结尾以W表示。Windows会如下定义:  

  #ifdef   UNICODE  

  #define   CreateWindowEx   CreateWindowExW  

  #else  

  #define   CreateWindowEx   CreateWindowExA  

  #endif   //   !UNICODE


推荐阅读
  • 基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析
    基址获取与驱动开发:内核中提取ntoskrnl模块的基地址方法解析 ... [详细]
  • 设计实战 | 10个Kotlin项目深度解析:首页模块开发详解
    设计实战 | 10个Kotlin项目深度解析:首页模块开发详解 ... [详细]
  • 本文探讨了Android系统中支持的图像格式及其在不同版本中的兼容性问题,重点涵盖了存储、HTTP传输、相机功能以及SparseArray的应用。文章详细分析了从Android 10 (API 29) 到Android 11 的存储规范变化,并讨论了这些变化对图像处理的影响。此外,还介绍了如何通过系统升级和代码优化来解决版本兼容性问题,以确保应用程序在不同Android版本中稳定运行。 ... [详细]
  • 本文深入探讨了CGLIB BeanCopier在Bean对象复制中的应用及其优化技巧。相较于Spring的BeanUtils和Apache的BeanUtils,CGLIB BeanCopier在性能上具有显著优势。通过详细分析其内部机制和使用场景,本文提供了多种优化方法,帮助开发者在实际项目中更高效地利用这一工具。此外,文章还讨论了CGLIB BeanCopier在复杂对象结构和大规模数据处理中的表现,为读者提供了实用的参考和建议。 ... [详细]
  • 本文探讨了利用Java实现WebSocket实时消息推送技术的方法。与传统的轮询、长连接或短连接等方案相比,WebSocket提供了一种更为高效和低延迟的双向通信机制。通过建立持久连接,服务器能够主动向客户端推送数据,从而实现真正的实时消息传递。此外,本文还介绍了WebSocket在实际应用中的优势和应用场景,并提供了详细的实现步骤和技术细节。 ... [详细]
  • 如何使用和示例代码解析 org.semanticweb.owlapi.model.OWLSubPropertyChainOfAxiom.getPropertyChain() 方法 ... [详细]
  • 在 Kubernetes 中,Pod 的调度通常由集群的自动调度策略决定,这些策略主要关注资源充足性和负载均衡。然而,在某些场景下,用户可能需要更精细地控制 Pod 的调度行为,例如将特定的服务(如 GitLab)部署到特定节点上,以提高性能或满足特定需求。本文深入解析了 Kubernetes 的亲和性调度机制,并探讨了多种优化策略,帮助用户实现更高效、更灵活的资源管理。 ... [详细]
  • Netty框架中运用Protobuf实现高效通信协议
    在Netty框架中,通过引入Protobuf来实现高效的通信协议。为了使用Protobuf,需要先准备好环境,包括下载并安装Protobuf的代码生成器`protoc`以及相应的源码包。具体资源可从官方下载页面获取,确保版本兼容性以充分发挥其性能优势。此外,配置好开发环境后,可以通过定义`.proto`文件来自动生成Java类,从而简化数据序列化和反序列化的操作,提高通信效率。 ... [详细]
  • Node.js 配置文件管理方法详解与最佳实践
    本文详细介绍了 Node.js 中配置文件管理的方法与最佳实践,涵盖常见的配置文件格式及其优缺点,并提供了多种实用技巧和示例代码,帮助开发者高效地管理和维护项目配置,具有较高的参考价值。 ... [详细]
  • 在MFC框架中,存在多个全局函数,用于在不同对象间获取信息或创建新对象。其中,`afxGetApp`函数尤为关键,它能够帮助开发者轻松获取当前应用程序的实例指针。本文将详细解析`afxGetApp`函数的内部机制及其在MFC应用程序中的具体应用场景,探讨其在提升代码可维护性和灵活性方面的优势。此外,还将介绍其他常用全局函数如`AfxWinInit()`和`AfxBeginThread()`的功能和使用方法,为开发者提供全面的参考。 ... [详细]
  • 在处理遗留数据库的映射时,反向工程是一个重要的初始步骤。由于实体模式已经在数据库系统中存在,Hibernate 提供了自动化工具来简化这一过程,帮助开发人员快速生成持久化类和映射文件。通过反向工程,可以显著提高开发效率并减少手动配置的错误。此外,该工具还支持对现有数据库结构进行分析,自动生成符合 Hibernate 规范的配置文件,从而加速项目的启动和开发周期。 ... [详细]
  • 在托管C++中开发应用程序时,遇到了如何声明和操作字符串数组的问题。本文详细探讨了字符串数组在托管C++中的应用与实现方法,包括声明、初始化、遍历和常见操作技巧,为开发者提供了实用的参考和指导。 ... [详细]
  • 在过去,我曾使用过自建MySQL服务器中的MyISAM和InnoDB存储引擎(也曾尝试过Memory引擎)。今年初,我开始转向阿里云的关系型数据库服务,并深入研究了其高效的压缩存储引擎TokuDB。TokuDB在数据压缩和处理大规模数据集方面表现出色,显著提升了存储效率和查询性能。通过实际应用,我发现TokuDB不仅能够有效减少存储成本,还能显著提高数据处理速度,特别适用于高并发和大数据量的场景。 ... [详细]
  • 在使用Keil C51创建51单片机项目时,启动代码中包含多个关键元素,这些元素确保了系统的正确初始化和运行。主要包括复位向量、中断向量表、系统时钟配置、寄存器初始化以及主函数入口等。这些组件共同协作,为后续的应用程序执行提供稳定的基础。 ... [详细]
  • 开发笔记:深入解析Android自定义控件——Button的72种变形技巧
    开发笔记:深入解析Android自定义控件——Button的72种变形技巧 ... [详细]
author-avatar
KL
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有