`
lovnet
  • 浏览: 6920026 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

UNICODE、ANSI字符集和字符串操作

阅读更多

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


Q UNICODE字符串如何显示
A
如果程序定义了_UNICODE宏直接用
WCHAR *str=L"unicodestring";
TextOut(0,0,str);
否则就需要转换类型
#include <comdef.h>
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

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

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

Q 如何编写符合ANSI和Unicode的应用程序?
A
(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)。

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

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

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

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

Q 如何得到汉字的Unicode编码
A
#include "comdef.h"
char *str1="你好";
_bstr_t str=str1;
WCHAR *str2=str;
str2就是你要的UNICODE码

Q 如何实现#21592#24037#36873#25321这种编码与汉字之间的转换?
A
CString str="#21592#24037#36873#25321";
str+='#';
CString str1="";
WCHAR str2[5]={0,0,0,0,0};
int j=0;
do
{
str1=str.Left(str.Find('#',1));
str=str.Mid(str.Find('#',1));
WCHAR i=0;
sscanf(str1,"#%d",&i);
str2[j]=i;
j++;
}while(str1!="");
_bstr_t str3=str2;
char *str4=str3;

Q 如何解决char* to bstr 和bstr to char *的问题
A
参考下面的函数完成
void charString()
{

char *l_sz;
l_sz=new char[20];
strcpy(l_sz,"hello world12你好!");

CString l_cstring(l_sz);
BSTR l_cBstr;
l_cBstr=l_cstring.AllocSysString();

CString l_cstring2(l_cBstr);

delete []l_sz;
cout<<"l_cstring:"<<l_cstring<<endl;
cout<<"l_cstring:"<<l_cstring2<<endl;

l_cstring2+="aaaa";
char *l_sz1;
l_sz1=l_cstring2.GetBuffer(l_cstring2.GetLength());
cout<<"l_sz:"<<l_sz1<<endl;
}

最后做一点补充说明:
asc长度为7位,共有128个字符,我们常用的英文字母和符号都包含在这里边。
ascII长度为8位,共有256个字符,前128个字符为asc.
ANSI长度为8位,共有256个字符。前128个字符也为asc.
ascII和ANSI只是在一些控制符号上有区别。
小插曲:C中的char 为signed char,除去第一个符号位,正好用7位来表示asc.
Unicode长16位,即2个字节,被C/C++定义成wchar_t.
OLECHAR在win32和Solaris OS中为16位,即2个字节,被C/C++定义成wchar_t.
OLECHAR在win16和MAC OS中为8位,即1个字节,被C/C++定义成char.
BSTR是一个包含长度前缀的OLECHAR数组。既它的长度不是由NULL结尾字符决定,而是由长度前缀决定。
BSTR不等于OLECHAR,OLECHAR也不等于UNICODE。

分享到:
评论

相关推荐

    ANSI字符串与Unicode字符串的相互转换

    ANSI字符串和Unicode字符串是两种常见的字符编码方式,它们各自有其特点和应用场景。本篇文章将详细探讨ANSI字符串与Unicode字符串的相互转换及其重要性。 首先,我们要理解ANSI字符串的概念。ANSI字符串实际上是一...

    Unicode与ANSI字符串之间的转换

    Unicode 和 ANSI 字符串编码方式都是广泛使用的字符表示形式。本文将深入探讨 Unicode 与 ANSI 字符串之间的转换原理及实现方法,并通过一个具体的示例来展示如何在 C/C++ 环境中实现这两种字符串类型的转换。 ### ...

    字符串十六进制转换工具(包含ANSI和UNICODE)

    在IT领域,字符串和十六进制转换是常见的操作,尤其在数据处理、编程以及网络通信中。本工具专注于ANSI和UNICODE字符串与十六进制之间的转换,这涉及到字符编码和二进制数据的理解。 首先,我们要理解ANSI和UNICODE...

    Unicode转换Ansi字符

    Unicode 的设计目标是兼容现有的字符集,同时解决不同语言和平台间的字符编码冲突问题。Unicode 可以用多种不同的字节序列表示,包括 UTF-8、UTF-16 和 UTF-32 等。 Ansi 编码,通常指的是基于 Windows 的“ANSI”...

    替换文件字符串 utf8 unicode ansi

    标题 "替换文件字符串 utf8 unicode ansi" 涉及的核心知识点主要集中在字符编码和文本处理上。在计算机科学中,字符编码是用来表示文本的数字系统,不同的编码标准有着不同的特性与适用场景。 1. **Unicode**:...

    精选_Ring0内核层下字符串基础操作之Ansi与Unicode字符串类型互转_源码打包

    在进行Ansi和Unicode字符串转换时,Windows提供了API函数来帮助开发者实现这一过程。这些函数包括但不限于以下几种: 1. **MultiByteToWideChar**: 这个函数用于将Ansi字符串转换为Unicode字符串。它需要输入Ansi...

    C语言UTF8到ANSI和Unicode转换代码

    C语言中进行字符编码转换,主要涉及字符串处理函数和内存操作。以下是一些基本步骤: 1. **UTF8到ANSI**:这个过程通常需要知道目标ANSI编码页(例如GBK),因为不同的ANSI编码页对应不同的字符集。首先,你需要...

    ANSI字符和宽字符

    在Windows操作系统中,ANSI字符集通常指的是Microsoft的扩展ASCII,包含了256个字符,其中包括ASCII标准的128个字符以及针对不同地区语言的附加字符。这些额外的字符通常用于表示非英文语言的特殊字符,如法语或德语...

    几种常见字符集以及字符串的转化方法.rar

    在C++中,非Unicode字符串操作通常涉及ANSI字符集。 3. Unicode字符集:Unicode是一种国际标准,旨在编码世界上所有的字符,它提供了超过100,000个代码点。在VC++中,可以使用WCHAR类型来存储Unicode字符,对应的...

    易语言Ansi与Unicode转换源码

    4. **写入Unicode文本**:将转换后的Unicode字符串写入新的文件,确保文件以Unicode编码保存。 5. **错误处理**:在转换过程中,可能会遇到无法识别的Ansi字符,这时需要决定如何处理,比如替换为默认字符,或者抛...

    ASCII码和Unicode中韩字符集(包括简体和繁体中文)很强大

    Unicode使用统一的编码空间,使得不同语言间的字符可以互相比较和操作。 Unicode有多种实现方式,其中最常见的是UTF-8编码。UTF-8是一种变长编码,它可以表示Unicode中的所有字符。对于英文字符,UTF-8与ASCII码...

    UTF8,ANSI,UTF7,UNICODE,UTF32等字符集字符串与字节数组互转工具

    本文将深入探讨UTF8、ANSI、UTF7、UNICODE和UTF32这五种字符编码格式,并介绍如何在它们之间进行转换以及字节数组与字符串之间的互换。 1. UTF8(Unicode Transformation Format - 8 bit): UTF8是最常见的...

    Unicode--宽字节字符集[文].pdf

    Unicode字符集是一种编码标准,旨在统一全球各种语言的文字表示,以解决不同地区和语言之间的文本数据交换问题。在软件开发中,尤其是涉及到多语言支持时,Unicode是至关重要的。宽字节字符集(如DBCS,Double Byte ...

    unicode字符串

    - "ANSI字符_UNICODE_宽字符_窄字符_多字节字符集.doc" 可能详细解释了宽字符和窄字符的概念,以及多字节字符集在Unicode中的角色。 - "在C和C++中使用Unicode.doc" 可能探讨了如何在C和C++编程语言中使用Unicode,...

    (资料大全加程序)C++ 字符串之间的相互转化 宽字符与多字符集(LPTSTR、LPCSTR、LPCTSTR、LPSTR)

    在C++编程中,字符和字符串的处理是至关重要的,特别是在处理不同的字符集时,如宽字符和多字符集。标题和描述中提到的关键概念包括LPTSTR、LPCSTR、LPCTSTR和LPSTR,这些都是在Windows API中常见的字符串类型指针。...

    utf-8 ansi 字符互转 工具

    在早期的Windows系统中,ANSI编码被广泛使用,但并不支持Unicode字符集,因此对于非英文字符,如中文、日文等,可能会出现乱码问题。 接下来,我们讨论如何进行UTF-8与ANSI之间的转换: 1. **手动转换**:在编程...

    EVC下UNICODE的字符串的输出问题

    - 在进行字符串复制或查找等操作时,需要使用相应的宽字符集函数(如 `wcscpy()` 和 `wcslen()`)。 - 在文件输入输出时,正确计算每个 Unicode 字符占用的空间,通常为两个字节。 - 当需要进行 Unicode 和 ANSI ...

    C语言中字符和字符串处理(ANSI字符和Unicode字符)

    ANSI字符和Unicode字符是两种不同的字符编码标准,它们用于表示不同范围和类型的字符。 ANSI字符通常指的是ASCII字符集,这是一个7位编码标准,包含了128个不同的字符,包括英文大小写字母、数字、标点符号以及一些...

    [C语言]字符串处理 - ANSI - Unicode - UTF8 转换

    - `WideCharToMultiByte()`:这是Windows API中的函数,用于将宽字符(Unicode)转换为多字节(如ANSI)字符串。 - `MultiByteToWideChar()`:此API函数用于将多字节字符串转换为宽字符字符串。 - `mbtowc()` 和 `...

Global site tag (gtag.js) - Google Analytics