`
isiqi
  • 浏览: 16488142 次
  • 性别: Icon_minigender_1
  • 来自: 济南
社区版块
存档分类
最新评论

Windows环境下Unicode编程总结

阅读更多

1. 如何取得一个既包含单字节字符又包含双字节字符的字符串的字符个数?
可以调用Microsoft Visual C++的运行期库包含函数_mbslen来操作多字节(既包括单字节也包括双字节)字符串。
调用strlen函数,无法真正了解字符串中究竟有多少字符,它只能告诉你到达结尾的0之前有多少个字节。


2. 如何对DBCS(双字节字符集)字符串进行操作?
函数 描述
PTSTR CharNext ( LPCTSTR ); 返回字符串中下一个字符的地址
PTSTR CharPrev ( LPCTSTR, LPCTSTR ); 返回字符串中上一个字符的地址
BOOL IsDBCSLeadByte( BYTE ); 如果该字节是DBCS字符的第一个字节,则返回非0值


3. 为什幺要使用Unicode?
(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字符串。


4. 如何编写Unicode源代码?
Microsoft公司为Unicode设计了WindowsAPI,这样,可以尽量减少代码的影响。实际上,可以编写单个源代码文件,以便使用或者不使用Unicode来对它进行编译。只需要定义两个宏(UNICODE和_UNICODE),就可以修改然后重新编译该源文件。
_UNICODE宏用于C运行期头文件,而UNICODE宏则用于Windows头文件。当编译源代码模块时,通常必须同时定义这两个宏。


5. Windows定义的Unicode数据类型有哪些?
数据类型 说明
WCHAR Unicode字符
PWSTR 指向Unicode字符串的指针
PCWSTR 指向一个恒定的Unicode字符串的指针
对应的ANSI数据类型为CHAR,LPSTR和LPCSTR。
ANSI/Unicode通用数据类型为TCHAR,PTSTR,LPCTSTR。


6. 如何对Unicode进行操作?
字符集 特性 实例
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


7. 如何表示Unicode字符串常量?
字符集 实例
ANSI “string”
Unicode L“string”
ANSI/Unicode T(“string”)或_TEXT(“string”)if( szError[0] == _TEXT(‘J’) ){ }


8. 为什幺应当尽量使用操作系统函数?
这将有助于稍稍提高应用程序的运行性能,因为操作系统字符串函数常常被大型应用程序比如操作系统的外壳进程Explorer.exe所使用。由于这些函数使用得很多,因此,在应用程序运行时,它们可能已经被装入RAM。
如:StrCat,StrChr,StrCmp和StrCpy等。


9. 如何编写符合ANSI和Unicode的应用程序?
(1) 将文本串视为字符数组,而不是chars数组或字节数组。
(2) 将通用数据类型(如TCHAR和PTSTR)用于文本字符和字符串。
(3) 将显式数据类型(如BYTE和PBYTE)用于字节、字节指针和数据缓存。
(4) 将TEXT宏用于原义字符和字符串。
(5) 执行全局性替换(例如用PTSTR替换PSTR)。
(6) 修改字符串运算问题。例如函数通常希望在字符中传递一个缓存的大小,而不是字节。这意味着不应该传递sizeof(szBuffer),而应该传递(sizeof(szBuffer)/sizeof(TCHAR)。另外,如果需要为字符串分配一个内存块,并且拥有该字符串中的字符数目,那幺请记住要按字节来分配内存。这就是说,应该调用
malloc(nCharacters *sizeof(TCHAR)),而不是调用malloc(nCharacters)。


10. 如何对字符串进行有选择的比较?
通过调用CompareString来实现。
标志 含义
NORM_IGNORECASE 忽略字母的大小写
NORM_IGNOREKANATYPE 不区分平假名与片假名字符
NORM_IGNORENONSPACE 忽略无间隔字符
NORM_IGNORESYMBOLS 忽略符号
NORM_IGNOREWIDTH 不区分单字节字符与作为双字节字符的同一个字符
SORT_STRINGSORT 将标点符号作为普通符号来处理


11. 如何判断一个文本文件是ANSI还是Unicode?
判断如果文本文件的开头两个字节是0xFF和0xFE,那幺就是Unicode,否则是ANSI。


12. 如何判断一段字符串是ANSI还是Unicode?
用IsTextUnicode进行判断。IsTextUnicode使用一系列统计方法和定性方法,以便猜测缓存的内容。由于这不是一种确切的科学方法,因此 IsTextUnicode有可能返回不正确的结果。


13. 如何在Unicode与ANSI之间转换字符串?
Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串;函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串。


14. Unicode和DBCS之间的区别
Unicode使用(特别在C程序设计语言环境里)“宽字符集”。「Unicode中的每个字符都是16位宽而不是8位宽。」在Unicode中,没有单单使用8位数值的意义存在。相比之下,在“双位组字符集”中我们仍然处理8位数值。有些位组自身定义字符,而某些位组则显示需要和另一个位组共同定义一个字符。
处理DBCS字符串非常杂乱,但是处理Unicode文字则像处理有秩序的文字。您也许会高兴地知道前128个Unicode字符(16位代码从0x0000到0x007F)就是ASCII字符,而接下来的128个Unicode字符(代码从0x0080到0x00FF)是ISO 8859-1对ASCII的扩展。Unicode中不同部分的字符都同样基于现有的标准。这是为了便于转换。希腊字母表使用从0x0370到0x03FF的代码,斯拉夫语使用从0x0400到0x04FF的代码,美国使用从0x0530到0x058F的代码,希伯来语使用从0x0590到0x05FF的代码。中国、日本和韩国的象形文字(总称为CJK)占用了从0x3000到0x9FFF的代码。Unicode的最大好处是这里只有一个字符集,没有一点含糊。


15.衍生标准
Unicode是一个标准。UTF-8是其概念上的子集,UTF-8是具体的编码标准。而UNICODE是所有想达到世界统一编码标准的标准。UTF-8标准就是Unicode(ISO10646)标准的一种变形方式,
UTF的全称是:Unicode/UCS Transformation Format,其实有两种UTF,一种是UTF-8,一种是UTF-16,
不过UTF-16使用较少,其对应关系如下:
在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 0xxxxxxx
在Unicode中编码为 0080 - 07FF 的 UTF-8 中编码形式为: 110xxxxx 10xxxxxx
在Unicode中编码为 0000 - 007F 的 UTF-8 中编码形式为: 1110xxxx 10xxxxxx 10xxxxxx


utf-8是unicode的一个新的编码标准,其实unicode有过好几个标准.我们知道一直以来使用的unicode字符内码都是16位,它实际上还不能把全世界的所有字符编在一个平面系统,比如中国的藏文等小语种,所以utf-8扩展到了32位,也就是说理论在utf-8中可容纳二的三十二次方个字符. UNICODE的思想就是想把所有的字符统一编码,实现一个统一的标准.big5、gb都是独立的字符集,这也叫做远东字符集,把它拿到德文版的WINDOWS上可能将会引起字符编码的冲突....早期的WINDOWS默认的字符集是ANSI.notepad中输入的汉字是本地编码,但在NT/2000内部是可以直接支持UNICODE的。notepad.exe在WIN95和98中都是ANSI字符,在NT中则是UNICODE.ANSI和UNICODE可以方便的实现对应映射,也就是转换 ASCII是8位范围内的字符集,对于范围之外的字符如汉字它是无法表达的。unicode是16位范围内的字符集,对于不同地区的字符分区分配,unicode是多个IT巨头共同制定的字符编码标准。如果在unicode环境下比如WINDOWS NT上,一个字符占两字节16位,而在ANSI环境下如WINDOWS98下一个字符占一个字节8位.Unicode字符是16位宽,最多允许65,535字符,数据类型被称为WCHAR。
对于已有的ANSI字符,unicode简单的将其扩展为16位:比如ANSI"A"=0x43,则对应的UNICODE为
"A"= 0x0043
而ASCII用七存放128个字符,ASCII是一个真正的美国标准,所以它不能满足其他国家的需要,例如斯拉夫语的字母和汉字于是出现了Windows ANSI字符集,是一种扩展的ASCII码,用8位存放字符,低128位仍然存放原来的ASCII码,
而高128位加入了希腊字母等
if def UNICODE
TCHAR = wchar
else
TCHAR = char
你需要在Project\Settings\C/C++\Preprocesser definitions中添加UNICODE和_UNICODE
UINCODE,_UNICODE都要定义。不定义_UNICODE的话,用SetText(HWND,LPCTSTR),将被解释为SetTextA(HWND,LPTSTR),这时API将把你给的Unicode字符串看作ANSI字符串,显示乱码。因为windows API是已经编译好存在于dll中的,由于不管UNICODE还是ANSI字符串,都被看作一段buffer,如"0B A3 00 35 24 3C 00 00"如果按ANSI读,因为ANSI字串是以'\0'结束的,所以只能读到两字节"0B A3 \0",如果按UNICODE读,将完整的读到'\0\0'结束。
由于UNICODE没有额外的指示位,所以系统必须知道你提供的字串是哪种格式。此外,UNICODE好象是ANSI C++规定的,_UNICODE是windows SDK提供的。如果不编写windows程序,可以只定义UNICODE。
开发过程:
围绕着文件读写、字符串处理展开。文件主要有两种:.txt和.ini文件
1. 在unicode和非unicode环境下字符串做不同处理的,那么需要参考以上9,10两条,以适应不同环境得字符串处理要求。
对文件读写也一样。只要调用相关接口函数时,参数中的字符串前都加上_TEXT等相关宏。如果写成的那个文件需要是unicode格式保存的,那么在创建文件时需要加入一个字节头。
CFile file;
WCHAR szwBuffer[128];

WCHAR *pszUnicode = L"Unicode string\n"; // unicode string
CHAR *pszAnsi = "Ansi string\n"; // ansi string
WORD wSignature = 0xFEFF;

file.Open(TEXT("Test.txt"), CFile::modeCreate|CFile::modeWrite);

file.Write(&wSignature, 2);

file.Write(pszUnicode, lstrlenW(pszUnicode) * sizeof(WCHAR));
// explicitly use lstrlenW function

MultiByteToWideChar(CP_ACP, 0, pszAnsi, -1, szwBuffer, 128);

file.Write(szwBuffer, lstrlenW(szwBuffer) * sizeof(WCHAR));

file.Close();
//以上这段代码在unicode和非unicode环境下都有效。这里显式的指明用Unicode来进行操作。
2. 在非unicode环境下,缺省调用的都是ANSI格式的字符串,此时TCHAR转换为CHAR类型的,除非显式定义WCHAR。所以在这个环境下,如果读取unicode文件,那么首先需要移动2个字节,然后读取得字符串需要用MultiByteToWideChar来转换,转换后字符串信息才代表unicode数据。
3. 在unicode环境下,缺省调用得都是unicode格式得字符串,也就是宽字符,此时TCHAR转换为WCHAR,相关得API函数也都调用宽字符类型的函数。此时读取unicode文件也和上面一样,但是读取得数据是WCHAR的,如果要转换成ANSI格式,需要调用WideCharToMultiByte。如果读取ANSI的,则不用移动两个字节,直接读取然后视需要转换即可。


某些语言(如韩语)必须在unicode环境下才能显示,这种情况下,在非unicode环境下开发,就算用字符串函数转换也不能达到显示文字的目的,因为此时调用得API函数是用ANSI的(虽然底层都是用UNICODE处理但是处理结果是按照程序员调用的API来显示的)。所以必须用unicode来开发。

分享到:
评论

相关推荐

    Windows程序设计-通透说UNICODE

    通过实际操作和案例分析,作者分享了在Windows环境下进行UNICODE编程的一些关键点和技术细节。 #### 什么是UNICODE? UNICODE是一种国际字符集标准,旨在支持世界上所有已知的文字和符号。在计算机科学中,UNICODE...

    VC下Unicode编程文档.docx

    因此,使用Unicode编程可以提高程序在Windows环境下的效率,尤其是在处理多语言文本时。 `WideCharToMultiByte`和`MultiByteToWideChar`是两个关键的API函数,用于在Unicode字符串和多字节字符集(MBCS)字符串之间...

    windows环境下GAWK version-4.2.1

    在Windows环境下使用`GAWK version 4.2.1`,用户可以享受到与Unix/Linux系统相同的文本处理能力,这对于Windows开发者和系统管理员来说是一个非常有用的工具。 `awk`的基本原理是基于模式匹配和动作执行。它可以在...

    在ANSI环境下读取Unicode文件

    总结来说,在ANSI环境下处理Unicode文件需要正确的识别文件编码,选择合适的文件打开模式,以及进行适当的字符编码转换。由于Unicode与ANSI编码之间存在本质上的不同,这就要求开发者在编程时必须特别注意编码转换的...

    OPC_client_在VC环境下编程

    相比于LPSTR,它可以存储Unicode字符,因此更适合处理多语言环境下的字符串数据。 4. **OPC接口**: - **IOPCServer**: 主要用于管理组对象,比如创建、删除、枚举组对象以及获取它们的状态。 - **IOPCItemMgt**: ...

    Windows驱动编程基础教程

    ### Windows驱动编程基础教程知识点概览 ...以上是对《Windows驱动编程基础教程》核心知识点的总结,该书通过系统地介绍内核API、示例代码以及关键技术和工具,为初学者提供了通往Windows驱动程序开发领域的有效途径。

    精通WindowsAPI 函数 接口 编程实例

    3.6 开发环境配置总结 66 第4章 文件系统 67 4.1 概述 67 4.1.1 文件系统的基本概念 67 4.1.2 文件系统主要API 68 4.2 磁盘和驱动器管理 70 4.2.1 遍历卷并获取属性 70 4.2.2 操作驱动器挂载点 76 ...

    Unicode转换成GBK

    本文将详细介绍如何利用C/C++编程语言实现从Unicode到GBK的编码转换。 #### 二、Unicode与GBK概述 1. **Unicode**:Unicode是一种通用的字符编码方式,它为每一个字符分配了一个唯一的数字,以便于在计算机上存储...

    程序员输入法unicode版

    考虑到程序员可能需要在不同的操作系统环境下工作,这款输入法应尽可能地支持Windows、macOS甚至Linux等主流操作系统,以满足不同平台下的编码需求。 7. **社区支持与更新** 开源或有活跃社区支持的输入法往往能...

    codetrans-.rar_codetrans_unicode_windows 8

    总结来说,这个压缩包提供的是关于字符编码转换的资源,特别是涉及多字节编码(如GBK)与Unicode(包括UTF-8)在Windows 8系统下的转换。这对于解决跨平台编码问题,尤其是处理来自不同编码环境的数据时非常有用。...

    Linux环境下Qt编程实验

    ### Linux环境下Qt编程实验知识点详解 #### 一、实验目的 - **掌握简单的Linux应用程序的编程**:在本实验中,参与者将学习如何在Linux环境下编写基本的应用程序。这不仅涉及编写代码,还包括理解Linux环境下的...

    sys_string_5.zip_unicode

    1. UniString.cpp、UniStringDemo.cpp、UniStringDemoView.cpp、UniStringDemoDoc.cpp:这些文件构成了一个简单的MFC(Microsoft Foundation Classes)应用程序,展示了如何在Windows环境下使用Unicode字符串。...

    精通Windows.API-函数、接口、编程实例.pdf

    在编译环境下进入demo目录,执行nmake命令在bin目录下生成可执行文件 注:demo无注释,对应书本中部分示例。 目录 第1章 Windows应用程序开发入门 1 1.1 第一个实例程序 1 1.1.1 start.exe 1 1.1.2 Windows ...

    精彩编程与编程技巧-VB中的Unicode 和 Ansi 格式...

    理解和灵活运用Unicode和Ansi格式在Visual Basic编程中至关重要,尤其是在处理多语言环境下的文本数据时。通过掌握`StrConv`函数和其他相关技术,程序员可以有效地解决字符编码问题,确保应用程序能够正确处理各种...

    批量转换unicode格式为ansi

    总结来说,批量转换Unicode格式到ANSI格式涉及字符编码的理解、文件读写操作、字符转换逻辑以及错误处理策略。"convertansi"工具或脚本通过自动化这些步骤,为用户提供了方便,特别是在需要处理大量文本文件的场合。...

    sem.rar_Windows编程

    总结起来,这个"sem.rar"压缩包中的代码集成了Java 2D API,专注于Windows环境下的汉字生成和字体管理,涵盖了从字体加载、字形渲染到复杂文本布局的多个环节。开发者可能通过这些类实现了高效且美观的汉字显示,...

    Unicode与ANSI字符串之间的转换

    在计算机编程领域,字符编码是将字符映射到二进制数据的一种方法,这对于文本处理至关重要。Unicode 和 ANSI 字符串编码方式都是广泛使用的字符表示形式。本文将深入探讨 Unicode 与 ANSI 字符串之间的转换原理及...

    unicode 字符显示

    在编程领域,Unicode 是一种...总结来说,C++处理Unicode字符涉及到编码转换、宽字符操作、以及了解目标环境的字符显示机制。通过实践和理解提供的示例代码,你可以增强在这方面的技能,为你的编程事业打下坚实的基础。

Global site tag (gtag.js) - Google Analytics