c语言多字节toutf8,C/C++语言拾遗(三)-多字节字符和Unicode

本文详细阐述了MFC中Unicode与多字节字符集的区别,包括各自的适用场景、字符串表示方式及转换方法,并介绍了如何在不同字符集间进行转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MFC字符集选项

a4c26d1e5885305701be709a3d33442f.pngMFC字符集选项

Unicode Character Set与Multi-Byte Character

Set有什么区别呢?

Multi-Byte Character

Set一般是指ANSI(多字节)字符集,关于ANSI请参考第二小节字符集(Charcater

Set)与字符编码(Encoding)​

而Unicode Character

Set就是Unicode字符集,一般是指UTF-16编码的Unicode。也就是说每个字符编码为两个字节,两个字节可以表示65535个字符,65535个字符可以表示世界上大部分的语言。

一般推荐使用Unicode的方式,因为它可以适应各个国家语言,在进行软件国际时将会非常便得。除非在对存储要求非常高的时候,或要兼容C的代码时,我们才会使用多字节的方式

一般MFC程序默认是unicode字符集的,字母和汉字都占两个字节。

而多字节字符集下,字母一个字节,汉字两个字节。

关于_T及L

_T 会根据你工程的设置自动转换UNICODE和非UNICODE. L

就是转为UNICODE

Visual

C++里边定义字符串的时候,用_T来保证兼容性,是一种数据类型,但是它不会产生结果,被编译系统的预处理系统来解释,VC支持ascii和unicode两种字符类型,用_T可以保证从ascii编码类型转换到unicode编码类型的时候,程序不需要修改。

​如果将来你不打算升级到unicode,那么也不需要_T!

_T是将字符串转换为TCHAR,TCHAR是一个宏定义,当定义了UNICODE时TCHAR等同于WCHAR,否则等同于CHAR。为了和以后的平台兼容,建议使用TCHAR,而不要使用普通的CHAR。例子:TCHAR

*s = _T("FSDF")

L将字符串转换为WCHAR,用于需要UNICODE的环境。例子:WCHAR *s = L"FSDF"

Unicode和UTF-8之间的关系

​Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

比如,汉字"严"的unicode是十六进制数4E25,转换成二进制数足足有15位(100111000100101),也就是说这个符号的表示至少需要2个字节。表示其他更大的符号,可能需要3个字节或者4个字节,甚至更多。

UTF-8就是在互联网上使用最广的一种Unicode的实现方式。其他实现方式还包括UTF-16(字符用两个字节或四个字节表示)和UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8是Unicode的实现方式之一。

UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

UTF-8的编码规则很简单,只有二条:

1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。

2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。

"严"的Unicode码是4E25,UTF-8编码是E4B8A5,两者是不一样的。它们之间的转换可以通过程序实现。

为什幺要使用Unicode?

​(1)

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

​(2)

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

​(3)

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

关于第三点​

​Windows

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

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

​数据类型

说明

​WCHAR

Unicode字符

​PWSTR

指向Unicode字符串的指针

​PCWSTR

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

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

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

​ANSI码(American National Standards

Institute)美国国家标准学会

的标准码。ANSI码

对于windows系统来说的话就是指当前的系统编码。如果是英文系统,那么ANSI码就是指ascii码,如果是中文系统的windows,比如xp,那么ANSI码就是指GBK​

如何表示Unicode字符串常量?

​字符集

实例

​ANSI“string”

​Unicode

L“string”

​ANSI/Unicode

T(“string”)或_TEXT(“string”)if( szError[0] == _TEXT(‘J’) ){

}​

​如何对Unicode进行操作?

​字符集 特性

实例ANSI 操作函数以str开头 strcpy

​Unicode

操作函数以wcs开头 wcscpy

​ANSI/Unicode

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

​ANSI/Unicode

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

​ANSI版本函数结尾以A表示;Unicode版本函数结尾以W表示。Windows会如下定义:

​#ifdef

UNICODE

​#define

CreateWindowEx CreateWindowExW

​#else

​#define

CreateWindowEx CreateWindowExA

​#endif //

!UNICODE

如何判断一个文本文件是ANSI还是Unicode?

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

如何判断一段字符串是ANSI还是Unicode?

用IsTextUnicode进行判断。IsTextUnicode使用一系列统计方法和定性方法,以便猜测缓存的内容。由于这不是一种确切的科学方法,因此

IsTextUnicode有可能返回不正确的结果。

如何在Unicode与ANSI之间转换字符串?

Windows函数MultiByteToWideChar用于将多字节字符串转换成宽字符串;函数WideCharToMultiByte将宽字符串转换成等价的多字节字符串。

char与wchar_t

我们知道C++基本数据类型中表示字符的有两种:char、wchar_t。

char叫多字节字符,一个char占一个字节,之所以叫多字节字符是因为它表示一个字时可能是一个字节也可能是多个字节。一个英文字符(如’s’)用一个char(一个字节)表示,一个中文汉字(如’中’)用3个char(三个字节)表示。

​wchar_t被称为宽字符,一个wchar_t占2个字节。之所以叫宽字符是因为所有的字都要用两个字节(即一个wchar_t)来表示,不管是英文还是中文。

在UNICODE编码格式下,CString 转换为

char*

转换示例:

​CString cstring=

"hello,bro

";

​char*

pcharbuf=new char;

​int iSize

= WideCharToMultiByte(CP_ACP, 0, cstring,

-1, NULL, 0, NULL, NULL);

WideCharToMultiByte(CP_ACP, 0, cstring,

-1, pcharbuf, iSize, 0,

0);

//WideCharToMultiByte()函数原型如下:

int

WINAPI

WideCharToMultiByte(

_In_ UINT

CodePage,//

指定要转换成的字符集代码页,CP_ACP

当前系统ANSI代码页

_In_ DWORD

dwFlags,//指定如何处理没有转换的字符

_In_NLS_string_(cchWideChar) LPCWCH

lpWideCharStr,  //待转换的宽字符串

_In_ int

cchWideChar,

//待转换宽字符串的长度,-1表示转换到字符串结尾。

_Out_writes_bytes_to_opt_(cbMultiByte, return) LPSTR

lpMultiByteStr,

//接收转换后输出新串的缓冲区。

_In_ int

cbMultiByte,

//输出缓冲区大小,如果为0,lpMultiByteStr将被忽略,函数将返回所需缓冲区大小而不使用lpMultiByteStr。

_In_opt_ LPCCH

lpDefaultChar,

_Out_opt_ LPBOOL

lpUsedDefaultChar

);

WideCharToMultiByte使用不当,会给影响程序的安全。调用此函数会很容易导致内存泄漏,因为lpWideCharStr指向的输入缓冲区大小是宽字符数,而lpMultiByteStr指向的输出缓冲区大小是字节数。为了避免内存泄漏,应确保为输出缓冲区指定合适的大小。可以先使cbMultiByte为0调用WideCharToMultiByte一次以获得所需缓冲区大小,为缓冲区分配空间,然后再次调用WideCharToMultiByte填充缓冲区。​

​参考链接:

​http://https//blog.youkuaiyun.com/openn/article/details/8249082

https://blog.youkuaiyun.com/luoweifu/article/details/49382969

​http://https//blog.youkuaiyun.com/youoran/article/details/8299731

​http://https//www.cnblogs.com/zhoudingcocng/p/6433960.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值