多字节字符与宽字符

多字节字符集——每个字符的编码宽度不一,可为一个字节或多个字节。

 (1)ASCII字符只占一个字节
 (2)对于中文、日文等用两个字节
 (3)一个字符串中,如何区分哪个是中文字符,那个是ASCII字符呢?

 “Windows程序设计”16进制(10进制)的编码

W

i

n

d

o

w

s

 

57

69

6E

64

6F

77

73

B3 CC

D0 F2

C9 E8

BC C6

0

87

105

110

100

111

119

115

-77 -52

-48 -14

-55 -24

-68 -58

0

 

  ①说明:ASCII码为一个字节,中文为两个字节,均为负数
  ②优点:节约内存。 
  ③缺点:每次查找,都需要从头到尾扫描,效率低。

    char c[] ="Windows程序设计";
    printf("%d\n",sizeof(c));  //输出16,数组总长度为16字节,含\0
    printf("%d\n",strlen(c));  //输出15,字符的长度为15个字节,不含\0

 

宽字节字符集——每个字符的编码宽度都相等,均是两个字节

(1)ASCII字符的处理。扩充为两个字节,在原先的字节前补充一个字节0x00
(2)结束符为两个\0
(3)字符串的解释都是两个字符为单位进行的。所以查找效率快,但内存占用大。

 “Windows程序设计”16进制的编码:

W

i

n

d

o

w

s

 

0057

0069

006E

0064

006F

0077

0073

7A0B

5E8F

8BBE

8BA1

0000

        wchar_t c[] = L"Windows程序设计";
        printf("%d\n",sizeof(c));  //输出24,数组总长度为16字节,含结束符
        printf("%d\n",wcslen(c));  //输出11,字符的长度为11个,不含结束符

兼容两种的字符集——如何兼容呢?

#ifdef _UNICODE
        #define _tcslen wcslen
        #define TCHAR wchar_t
        #define LPTSTR wchar_t*
        #define _T(x) L##x
#else
        #define _tcslen strlen
        #define TCHAR  char
        #define LPTSTR  char*
        #define _T(x)  x
#endif

【例】TCHAR c[] = _T("Windows程序设计");

    //多字节字符集下
    printf("%d\n",sizeof(c));  //16
    printf("%d\n",_tcslen(c)); //15

    //宽字符集下
    printf("%d\n",sizeof(c));  //24
    printf("%d\n",_tcslen(c)); //11

字符集的对比

 

ASCII

Unicode

通用版本

字符类型

char\CHAR

wchar_t\WCHAR

TCHAR

函数两种版本

printf
strlen
MessageBoxA

wprintf
wcslen
MessageBoxW

_tprintf 
_tcslen
MessageBox宏:TEXT\_TEXT
     _T\__T

 【例】

#include <stdio.h>
#include <locale.h>
#include <tchar.h>

int main()

{
    //ASCII字符集
    //char c = 'A'; //char为一个字节
     //char str[] = "中国";  //在未出现Unicode前的用法,在求字符串长度时会出问题。
     //printf("%c\n", c);
     //printf("%s\n", str);
     //printf("长度:%d\n",strlen(str));//长度为4,对于ASCII来说,一个汉字为2个字节,被看成是两个字符了。

    //Unicode字符集
    //wchar_t c = L'中'; //Unicode,两个字节
    //wchar_t str[] = L"中国";  //Unicode字符串的用法
    //setlocale(LC_ALL,"chs");
    //wprintf(L"%lc\n", c);//wprintf要求第1个参数为L型的,须加个大写的L
    //wprintf(L"%ls\n",str);
    //wprintf(L"%d\n",wcslen(str));//长度为2,Unicode字符。注意与上面ASCII字符集的比较

    //通用的类型与函数
    TCHAR str[] = _T("中国");
     setlocale(LC_ALL,"chs");
     _tprintf(_T("%s\n"),str);
     _tprintf(_T("%d\n"),_tcslen(str));
     return 0;
 }

Windows中的字符串函数

通用版本

C语言中的ASCII版本

lstrlen

strlen

Lstrcpy

strcpy

Lstrcpyn

strcpyn

lstrcat

strcat

lstrcmp

strcmp

lstrcmpi

strcmpi

//ASCII码版
int WINAPI WinMain(HINSTANCEhInstance,HINSTANCE hPrevInstance,PSTR szCmdLine,int iCmdShow)
 {   
      int a= 12;
      char szBuffer[100];
      sprintf_s(szBuffer,100,"Hello %d\n", a); //在内存中格式化字符串,标准c语言版本
      MessageBoxA(NULL,szBuffer, "Hello ASCII", MB_OK | MB_ICONINFORMATION); //带A
      return0;
 }

//Unicode版

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
 {
      int a= 12;
      wchar_tszBuffer[100];  //WCHAR
      swprintf_s(szBuffer,100, L"Hello %d\n", a); //在内存中格式化字符串,标准c语言版
      MessageBoxW(NULL,szBuffer, L"Hello Unicode", MB_OK | MB_ICONINFORMATION); //带W
      return0;
 }

 //通用版本

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)

{
       int a= 12;
       TCHARszBuffer[100];  //WCHAR
       _stprintf_s(szBuffer,100,TEXT("Hello %d\n"), a); //在内存中格式化字符串,微软版本的在tchar.h中
       MessageBox(NULL,szBuffer, TEXT("Hello TCHAR"), MB_OK | MB_ICONINFORMATION);
       return0;
 }

 

### C++ 中多字节字符宽字节字符的区别及用法 #### 1. 基本定义 多字节字符是指字符的存储大小不固定,可能占用多个字节来表示单个字符。这种编码方式通常用于支持多种语言环境下的字符集,例如 UTF-8 或 GBK 编码[^1]。 相比之下,宽字符是一种固定的字节宽度表示方法,其典型实现为 `wchar_t` 类型,在大多数平台上占 2 或 4 字节。无论具体字符为何,宽字符始终占据相同的内存空间。 --- #### 2. 数据类型差异 在 C++ 中,多字节字符一般通过普通的 `char` 数组表示,而宽字符则使用专门的数据类型 `wchar_t` 表示: ```cpp // 多字节字符字符串 const char* mbString = "你好"; // 宽字符字符串 const wchar_t* wcString = L"你好"; ``` 上述代码展示了两种不同类型的字符串声明方式。注意宽字符字符串前需加上前缀 `L` 来区分[^2]。 --- #### 3. 转换机制 由于多字节字符宽字符之间存在本质上的差别,因此两者之间的转换不可避免涉及底层字符集的支持。以下是常见的转换函数及其用途: - **Windows 平台** - `_mbstowcs_s`: 将多字节字符串转换为宽字符字符串。 - `_wcstombs_s`: 将宽字符字符串转换回多字节字符串。 - **Linux/POSIX 平台** - `mbstowcs`: 实现类似的多字节宽字符转换功能。 - `wcstombs`: 提供反向操作的功能。 这些函数的核心在于它们依赖于当前系统的区域设置(locale)。不同的 locale 可能对应完全不同的字符映射关系。 --- #### 4. 使用场景分析 ##### (1)多字节字符适用场合 当应用程序运行在一个特定的语言环境中,并且该环境下使用的字符集较为简单时,可以优先考虑采用多字节字符处理方案。比如中文 Windows 系统默认使用 GBK 编码,此时直接利用多字节字符即可满足需求[^3]。 另外需要注意的是,UTF-8 是一种变长编码形式,虽然理论上属于广义上的多字节范畴,但由于其兼容 ASCII 的特性以及跨平台优势,在现代开发中被广泛接受并应用。 ##### (2)宽字符适合情况 对于需要统一管理各种复杂文字系统的情况来说,选用宽字符更为合适。因为每种字符都分配相同的空间量级,从而简化了许多内部逻辑运算过程。特别是在国际化软件设计领域里,推荐尽可能多地采纳宽字符技术路线。 然而值得注意的一点是,随着 Unicode 技术的发展,尤其是 UTF-16 UTF-32 这些基于固定单位长度的标准逐渐成为主流之后,“传统意义上的”宽字符概念正在慢慢淡出历史舞台——毕竟后者本质上也是某种特殊形态下的 Unicode 表达而已! --- #### 5. 编码方式对比 | 特性 | 多字节字符 | 宽字符 | |--------------------|-------------------------------------|-------------------------------------| | 存储单元 | 不同字符可占用不同数量的字节 | 所有字符均占有相等数量的字节 | | 主流编码实例 | UTF-8, GBK | UTF-16 (部分), UCS-2 | | 性能影响 | 访问效率较低 | 更高的访问速度 | | 内存消耗 | 较低 | 高 | 以上表格总结了两者的若干重要属性比较结果. --- ### 示例代码展示 下面给出一段简单的例子演示如何完成基本的相互转化工作: ```cpp #include <iostream> #include <cwchar> // 包含宽字符头文件 using namespace std; int main(){ const char *mbs="测试"; size_t len=mbstowcs(NULL,mbs,0)+1; // 获取所需缓冲区大小 wchatr_t *wcs=new wchar_t[len]; if(mbstowcs(wcs,mbs,len)!=(size_t)-1){ cout << "成功转换:" << wcs << endl; } delete[] wcs; } ``` 此段程序片段实现了从常规字符串至宽字符版本间的转变流程说明。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值