UNICODE编码

  本例介绍了C语言使用的两种字符集, 多字节编码字符集(GBK, UTF-8等)和UNICODE(UCS-2)字符集以及它们的区别。

  从程序中我们可以学习到, 除过早期C语言支持的ASCII编码外, 新的C语言还支持多字节编码和UNICODE编码, 后两者都这是一种可以包含国际化文字的编码格式, 而且从Windows2000之后系统内核统一采用UNICODE文字编码格式。

  C语言同时支持多字节编码和UNICODE编码, 所以对应的数据类型也就提供了两个, char类型和wchar_t类型。对应的字符、字符串操作函数也同时提供了两套, 普通的C标准字符串函数库和以w开头的UNICODE版本扩展函数库(注意, 原有以str开头的字符串函数, 其UNICODE版本是以wcs开头的)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <locale.h>

// 定义缓冲区长度为256个字符
// (注意, 这里为什么用"字符"而不是"字节")
#define BUFFER_LEN 256

int main(int argc, char* argv[]) 
{
    // 定义一个ASCII字符变量
    char ce = 'A';
    // 定义一个UNICODE字符变量
    wchar_t wce = 'A';

    //    定义一个ASCII字符串变量, 包含一个汉字
    // (由于一个汉字占用2字节(GB10080编码)), 
    //    所以一个char类型变量无法存储, 需要一个字符串来存储, 
    // 所以实际上这个“大”字占据了3个字节, 两个字节存放字符
    // 本身编码, 还有一个/0结束符
    char szC[] = "大";
   
    //    定义一个UNICODE字符变量, wchar_t变量可以存放一个汉
    // 字, 注意字符前的大写L, 这个符号表示该字符为UNICODE字
    // 符集字符
    wchar_t wcC = L'大';

    // 定义ASCII字符集字符串变量
    const char cszHello[] = "Hello";
   
    //    定义UNICODE字符集字符串变量, 注意字符串前的大写L,
    // 这个符号表示该字符串为UNICODE字符集字符串
    const wchar_t cwszHello[] = L"Hello";

    /*********************************************************
     *    学习字符集, 一开始要搞清楚不同字符集占据的空间大小。
     *    ASCII字符集每个字符占据1字节, 使用char表示
     *    UNICODE字符集每个字符占据2字节, 使用wchar_t(部分
     * 版本C语言使用unsigned short)表示
     *********************************************************/

    //    定义ASCII字符集字符串指针
    // (思考一下, pcszHello和cszHello这两个变量定义的区别在
    // 哪里, 它们各自代表了什么?)
    const char* pcszHello = "大家好";
   
    // 定义UNICODE字符集字符串指针
    const wchar_t* pcwszHello = L"大家好";

    //    定义BUFFER_LEN长度存放字节的缓冲区
    // (定义的同时初始化缓冲区是一个好习惯)
    char szBuffer[BUFFER_LEN] = "";
   
    // 定义BUFFER_LEN长度存放UNICODE字符的缓冲区
    wchar_t wszBuffer[BUFFER_LEN];

    // 使用memset函数可以初始化任何数组, 包括字符串数组
    memset(wszBuffer, 0, sizeof(wszBuffer));

    //    在最新的C语言标准中, 所有UNICODE字符在显示前需要
    // 设置其国家代码(或称为地域信息), 这里设置为中国
    //    LC_ALL表示设置所有相关项目为中国, 包括文字、时间和
    // 货币
    _wsetlocale(LC_ALL, L"zhi");

    // 输出ASCII英文字符
    printf("size of %c is %d, code is: %u", ce, sizeof(ce), (int)ce);
   
    // 输出UNICODE英文字符
    wprintf(L"/nsizeof %c is %d, code is: %u", wce, sizeof(wce), (int)wce);

    /*********************************************************
     *    通过上述代码可以发现, 对于英文字符, ASCII编码和
     * UNICODE编码的内码相同, 但占用空间不同
     *********************************************************/

    // 输出ASCII中文字符(实际是一个字符串)
    printf("/nsize of %s is %d, code is: %u", szC, sizeof(szC), (int)*(unsigned short*)szC);
   
    // 输出UNICODE中文字符
    wprintf(L"/nsizeof %c is %d, code is: %u", wcC, sizeof(wcC), (int)wcC);

    /*********************************************************
     *    通过上述代码可以发现, GB10080编码和UNICODE编码在
     * 编码“大”字时, 编码值是不同的, 但都占据2字节空间
     *********************************************************/
   
    // 使用printf函数输出ASCII字符集字符串并输出其占据空间的字节数
    printf("/nsize of %s is %d", cszHello, sizeof(cszHello));
   
    // 使用wprintf函数输出UNICODE字符集字符串并输出其占据空间的字节数
    wprintf(L"/nsize of %s is %d", cwszHello, sizeof(cwszHello));
   
    /*********************************************************
     * 通过上述的练习可以发现:
     *    ASCII字符集字符串长度和其占用空间的字节数一致
     * (包括结束符/0, 占据1 byte)
     *    UNICODE字符集字符串长度是其占用空间字节数的2倍
     * (包括结束符/0, 占据2 byte), 这一点和wchar_t类型为2字
     * 节一致
     *********************************************************/
   
    // 使用strlen函数测量ASCII字符串长度
    printf("/nlength of %s is %d", pcszHello, strlen(pcszHello));
   
    // 使用wcslen函数测量UNICODE字符串长度
    wprintf(L"/nlength of %s is %d", pcwszHello, wcslen(pcwszHello));

    // 使用strcpy_s函数复制ASCII字符串(后缀为_s的函数是原函数的"安全版本", 
    // 改进了可能出现缓冲区溢出问题的漏洞)
    strcpy_s(szBuffer, BUFFER_LEN, cszHello);
   
    // 使用strcat_s函数连接ASCII字符串
    strcat_s(szBuffer, BUFFER_LEN, pcszHello);
    printf("/nlength of %s is %d", szBuffer, strlen(szBuffer));

    // 使用wcscpy_s函数复制UNICODE字符串
    wcscpy_s(wszBuffer, BUFFER_LEN, cwszHello);
   
    // 使用wcscat_s函数连接UNICODE字符串
    wcscat_s(wszBuffer, BUFFER_LEN, pcwszHello);
    wprintf(L"/nlength of %s is %d", wszBuffer, wcslen(wszBuffer));

    wprintf(L"/n");
    system("pause");
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值