宽字符与Unicode (c语言 汉语字符串长度)
在C语言中,我们使用char来定义字符,占用一个字节,最多只能表示128个字符,也就是ASCII码中的字符。计算机起源于美国,char 可以表示所有的英文字符,在以英语为母语的国家完全没有问题。
但是世界上存在很多不同的语言,例如汉语、汉语、日语等有成千上万个字符,需要用多个字节来表示,称之为宽字符(Wide Character)。Unicode 是宽字符编码的一种,已经被现代计算机指定为默认的编码方式,Windows 2000以后的操作系统,包括Windows 2000、XP、Vista、Win7、Win8、Win10、Windows Phone、Windows Server 等(它们统称为 Windows NT)都从底层支持Unicode,存取效率比 char 要高。
更多内容请查看:ASCII编码与Unicode编码
C语言中的宽字符
在C语言中,使用wchar.h头文件中的wchar_t来定义宽字符,例如:
wchar_t ch = 'A';
wchar_t 被定义为typedef unsigned short wchar_t,和一个无符号整型一样,占用两个字节。
如果定义宽字符串,需要加前缀L,例如:
wchar_t *str = L"C语言中文网";
L是必须要加的,并且与字符串之间不能有空格,只有这样编译器才知道每个字符占用两个字节。
宽字符示例:
- #include <stdio.h>
- #include <wchar.h>
- int main(){
- char ch = 'A';
- wchar_t wch = 'A';
- char str[] = "C语言中文网";
- wchar_t wstr[] = L"C语言中文网";
- printf("ch=%d, wch=%d, str=%d, wstr=%d\n", sizeof(ch), sizeof(wch), sizeof(str), sizeof(wstr));
- return 0;
- }
运行结果:
ch=1, wch=2, str=12, wstr=14
wstr 之所以比 str 多两个字节是因为:字符 'C' 占用两个字节,字符串结束标志 '\0' 也占用两个字节。
宽字符串的长度
计算ASCII字符串长度使用 strlen 函数,计算宽字符串长度使用 wcslen 函数:
- #include <stdio.h>
- #include <wchar.h>
- #include <string.h>
- int main(){
- char str[] = "C语言中文网";
- wchar_t wstr[] = L"C语言中文网";
- printf("strlen(str)=%d, wcslen(wstr)=%d\n", strlen(str), wcslen(wstr));
- return 0;
- }
运行结果:
strlen(str)=11, wcslen(wstr)=6
strlen 的运行结果显然不正确,因为它把一个字节作为一个字符计算,而 wcslen 把两个字节作为一个字符计算。
注意:wcslen 在 string.h 和 wchar.h 头文件中均有说明。
维护一个版本的源代码
在 Windows NT 以前的操作系统中,甚至包括 Windows 98,对宽字符的支持都不是很好,所以大多情况下使用ASCII编码。Windows NT 推出以后,已经从底层支持了Unicode,所以在 Windows NT 上的程序大多使用Unicode。
如果你希望程序能够在各种版本的Windows操作系统中运行,那么就需要维护两个版本的源代码,ASCII 版和 Unicode 版。ASCII 字符和 Unicode 字符的定义、使用都不一样,要想在一个版本的源代码中做兼容处理会非常困难,要做大量的工作,对程序员来说简直是噩梦。
不过,Windows 又为我们做了一件好事,已经处理了兼容性问题。它是怎么做到的呢?
例如对于字符串,ASCII 中使用 char 来定义,而 Unicode 中使用 wchar_t 来定义,并且需要添加前缀L。那么在 windows.h 头文件中(或者是它包含的其他头文件)就这样来处理:
- #ifdef UNICODE
- typedef wchar_t TCHAR;
- #define TEXT(quote) L##quote
- #else
- typedef char TCHAR
- #define TEXT(quote) quote
- #endif
我们在源码中可以这样来使用:
TCHAR str[] = TEXT("C语言中文网");
如果是Unicode版,也就是定义了UNICODE宏,那么上面的语句等价于:
wchar_t str[] = L"C语言中文网";
如果是ASCII,也就是没有定义UNICODE宏,那么等价于:
char str[] = "C语言中文网";
在Windows中,随处可见这样的处理。虽然现代操作系统都已经支持Unicode,无需再考虑与ASCII的兼容性问题,但是依然要为这些历史问题付出代价。
总结:由于各种各样的原因,我们优先使用Windows定义的数据类型、宏、结构体等,这样编写的程序兼容性较好,不用考虑ASCII和Unicode的问题。但这也带来了一个挑战,就是要熟悉Window定义的数据类型、宏、结构体等。
宽字符与Unicode (c语言 汉语字符串长度)的更多相关文章
- 要求产生10个随机的字符串,每一个字符串互相不重复,每一个字符串中组成的字符(a-zA-Z0-9)也不相同,每个字符串长度为10;
package text1; import java.util.ArrayList; import java.util.HashSet; /* * 要求产生10个随机的字符串, * 每一个字符串互相不 ...
- YTU 2417: C语言习题 字符串长度
2417: C语言习题 字符串长度 时间限制: 1 Sec 内存限制: 128 MB 提交: 758 解决: 548 题目描述 写一函数,求一个字符串的长度.在main函数中输入字符串,并输出其长 ...
- c语言 判断字符串长度 实现
/* 首先明白答案的本质(该函数)是一个计数器该计数器用for循环来实现实现对一串字符串的计数字符串以空格开头 不计算空格 计算空格后的数字直到遇到\0结束.num计算器字符串不以空格结束 计算空格后 ...
- 彻底弄懂UTF-8、Unicode、宽字符、locale
目录 Unicode.UCS UTF8 宽字符类型wchar_t locale 为什么需要宽字符类型 多字节字符串和宽字符串相互转换 最近使用到了wchar_t类型,所以准备详细探究下,没想到水还挺深 ...
- [转帖]彻底弄懂UTF-8、Unicode、宽字符、locale
彻底弄懂UTF-8.Unicode.宽字符.locale linux后端开发 已关注 彻底弄懂UTF-.Unicode.宽字符.locale unicode 是字符集 utf-8是编码格式.. ...
- 关于MultiByteToWideChar与WideCharToMultiByte代码测试(宽字符与多字节字符的转换)以及字符串的转换代码测试
#pragma once #include <stdio.h> //getchar() #include <tchar.h> #include <stdlib.h> ...
- windows 编程—— 宽字符集 与 Unicode
目录: 从ASCII码 到 Unicode Windows 编程中的 "字符” 定义 (如何在windows下进行通用编码) 常用的通用函数,定义 (本文为学习<Programming ...
- C语言里字符串的解析
根据给定的字符串,按照一定规则解析字符串,卡住好几次,这次做个笔记,以供参考 函数名称: strtok 函数原型: char *strtok(char *s1, const char *s ...
- [c/c++] programming之路(25)、字符串(六)——memset,Unicode及宽字符,strset
一.memset #include<stdio.h> #include<stdlib.h> #include<memory.h> void *mymemset(vo ...
随机推荐
- 关联mysql失败_Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezon' 时区错误
时区错误,MySQL默认的时区是UTC时区,比北京时间晚8个小时. 所以要修改mysql的时长 在mysql的命令模式下,输入: set global time_zone='+8:00'; 再次连接成 ...
- 打造游戏金融小程序行业测试标准腾讯WeTest携各专家共探品质未来
在获客成本不断上升的时代里,产品品质愈发是互联网应用的决胜标准.随着用户需求更加多样,开发者不仅要深挖应用功能,更需要面向业务所在领域,建立全面.专业的测试架构,掌控开发进度.提高开发效率,才能在互联 ...
- JavaScript调用百度地图
在网站开发过程中,经常会调用到地图,百度地图提供Web开发.Android开发.iOS开发API及SDK,百度地图JavaScript API可帮助您在网站中构建功能丰富.交互性强的地图应用,本篇博客 ...
- ios路线
http://www.cocoachina.com/ios/20150303/11218.html
- vue学习指南:第一篇 - vue的介绍
三大主流框架: 1. Vue.js 是目前最火的一个前端框架,react是最流行的前端框架 (react除了开发网站,还可以开发手机app,Vue语法也是可以用于手机App开发的,需要借助于wexx) ...
- web下载附件及修改名称
/** * @param: url 附件地址 * @param: filename 下载后的文件名 */ function download(url, filename) { getBlob(url, ...
- RHEL7.5 静默安装(silent mode)oracle11gr2数据库软件
如果没有图形界面多可怕,或者图形界面安装总报些奇怪的错误多可怕,静默安装数据库软件了解一下 修改主机名.关闭selinux [root@localhost ~]$ sed -i '3,$d' /etc ...
- odoo10学习笔记五:高级视图
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/11189279.html 树视图 tree视图表现出来是列表视图,列表中一行一纪录.可以根据每行纪录的某字段值 ...
- 获取APK的appPackage和appActivity
[法二]AndroidSDK 此方法是采用AndroidSDK\build-tools\23.0.2(这个版本号可能不一定,但是一般每个版本号里面都,任意即可)\aapt.exe aapt dump ...
- 使用设备树来编写led驱动程序
在总线设备驱动模型中,平台设备是写在c文件中.使用设备树时,平台设备事先并不存在,在dts文件中构造节点,节点里面含有资源.dts文件被编译成dtb文件,然后传递给内核.内核会解析dtb文件,得到一个 ...