宽字符与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是必须要加的,并且与字符串之间不能有空格,只有这样编译器才知道每个字符占用两个字节。

宽字符示例:

  1. #include <stdio.h>
  2. #include <wchar.h>
  3. int main(){
  4. char ch = ‘A‘;
  5. wchar_t wch = ‘A‘;
  6. char str[] = "C语言中文网";
  7. wchar_t wstr[] = L"C语言中文网";
  8. printf("ch=%d, wch=%d, str=%d, wstr=%d\n", sizeof(ch), sizeof(wch), sizeof(str), sizeof(wstr));
  9. return 0;
  10. }

运行结果:
ch=1, wch=2, str=12, wstr=14

wstr 之所以比 str 多两个字节是因为:字符 ‘C‘ 占用两个字节,字符串结束标志 ‘\0‘ 也占用两个字节。

宽字符串的长度

计算ASCII字符串长度使用 strlen 函数,计算宽字符串长度使用 wcslen 函数:

  1. #include <stdio.h>
  2. #include <wchar.h>
  3. #include <string.h>
  4. int main(){
  5. char str[] = "C语言中文网";
  6. wchar_t wstr[] = L"C语言中文网";
  7. printf("strlen(str)=%d, wcslen(wstr)=%d\n", strlen(str), wcslen(wstr));
  8. return 0;
  9. }

运行结果:
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 头文件中(或者是它包含的其他头文件)就这样来处理:

  1. #ifdef UNICODE
  2. typedef wchar_t TCHAR;
  3. #define TEXT(quote) L##quote
  4. #else
  5. typedef char TCHAR
  6. #define TEXT(quote) quote
  7. #endif

我们在源码中可以这样来使用:

TCHAR str[] = TEXT("C语言中文网");

如果是Unicode版,也就是定义了UNICODE宏,那么上面的语句等价于:

wchar_t str[] = L"C语言中文网";

如果是ASCII,也就是没有定义UNICODE宏,那么等价于:

char str[] = "C语言中文网";

在Windows中,随处可见这样的处理。虽然现代操作系统都已经支持Unicode,无需再考虑与ASCII的兼容性问题,但是依然要为这些历史问题付出代价。

总结:由于各种各样的原因,我们优先使用Windows定义的数据类型、宏、结构体等,这样编写的程序兼容性较好,不用考虑ASCII和Unicode的问题。但这也带来了一个挑战,就是要熟悉Window定义的数据类型、宏、结构体等。

原文地址:https://www.cnblogs.com/qiumingcheng/p/11334777.html

时间: 2024-10-10 01:26:46

宽字符与Unicode (c语言 汉语字符串长度)的相关文章

C语言--求字符串长度的三种解法

问题: 求一个字符串的三种解法 一.计数的方法 #include<stdio.h> #include<assert.h> int my_strlen( char* str) { int count=0; while (*str) { count++; str++; } return count; } int main(void) { char *arr = "abcef"; int ret = my_strlen(arr); printf("%d\n&

彻底弄懂UTF-8、Unicode、宽字符、locale

目录 Unicode.UCS UTF8 结论: 宽字符类型wchar_t locale 为什么需要宽字符类型 多字节字符串和宽字符串相互转换 最近使用到了wchar_t类型,所以准备详细探究下,没想到水还挺深,网上的资料大多都是复制粘贴,只有个结论,也没个验证过程.本文记录探究的过程及结论,如有不对请指正. Unicode.UCS UCS(Universal Character Set)本质上就是一个字符集. Unicode的开发结合了国际标准化组织所制定的?ISO/IEC 10646,即通用字

windows 编程 —— 宽字符集 与 Unicode

从ASCII码 到 Unicode 双字节字符集 迄今为止,我们已经看到了256个字符的字符集(ASCII).但中国.日本和韩国的象形文字符号有大约21,000个.如何容纳这些语言而仍保持和ASCII的某种兼容性呢? 解决方案(如果这个说法正确的话)是双字节字符集(DBCS:double-byte character set).DBCS从256代码开始,就像ASCII一样.与任何行为良好的代码页一样,最初的128个代码是ASCII.然而,较高的128个代码中的某些总是跟随着第二个字节.这两个字节

C语言反转字符串

1.使用string.h中的strrev函数 #include <iostream> #include <cstring> using namespace std; int main() { char s[]="hello"; strrev(s); cout<<s<<endl; return 0; } 2.使用algorithm中的reverse函数 #include <iostream> #include <strin

C语言08字符串 &amp; 预处理 &amp; 结构体

项目开发中字符串模型建立 strstr的while dowhile模型 //int cltClient_rev(void *handle, unsigned char *buf, int *buflen) //不要相信别人给你传送的内存地址是可用的 int getCout(char *str, char *substr, int *count) { int rv = 0; char *p = str; int ncout = 0; if (str==NULL || substr== NULL |

C语言里字符串的解析

原文网摘:http://www.cnblogs.com/yi-meng/p/3620244.html#undefined 根据给定的字符串,按照一定规则解析字符串,卡住好几次,这次做个笔记,以供参考 函数名称:   strtok 函数原型:   char *strtok(char *s1, const char *s2) 函数功能:   分解s1字符串为用特定分隔符分隔的多个字符串(一般用于将英文句分解为单词) 函数返回:   字符串s1中首次出现s2中的字符前的子字符串指针 参数说明:   s

字符串长度计算

字符串的长度通常是指字符串中包含字符的数目,但有的时候人们需要的是字符串所占字节的数目.常见的获取字符串长度的方法包括如下几种. 1.使用sizeof获取字符串长度 sizeof的含义很明确,它用以获取字符数组的字节数(当然包括结束符\0).对于ANSI字符串和UNICODE字符串,形式如下: sizeof(cs)/sizeof(char) sizeof(ws)/sizeof(wchar_t) 可以采用类似的方式,获取到其字符的数目.如果遇到MBCS,如"中文ABC",很显然,这种办法

宽字符,Ansic和Unicode

电脑发展的初期,只是在美国等英文国家使用,英文只有26个字母和其它字符,一个字节最多可以表示256个字符,如字母“A”用0x41(二进制01000001)表示,字母“a”用0x61(二进制01100001)表示.为了使各家电脑公司生产的电脑统一,美国搞了个国家标准ANSI,一直沿用至今,我们今天用的电脑普通情况下使用的都ANSI编码. ANSI编码,每个字符占一个字节,但最多只能表示256个字符.汉字等东亚语言字符怎么办呢?于是采用两个字节共同表示一个汉字的方法.二个字节理论上可以表示65535

宽字符、多字节、unicode、utf-8、gbk编码转化

今天遇到一个编码的问题,困惑了我很长时间,所以就简要的的了解了一下常用的编码类型. 我们最常见的是assic编码,它是一种单字节编码,对多容纳256个字符. 我们在编程的时候经常遇到unicode,unicode是一种宽字节编码,能够很好的融合世界各个国家的字符,具有国际通用性,所谓宽字符其实使用两个字节来表示一个符号. 而utf8是一种多字节编码,一个字符所占用的字节数不确定,是对unicode的精简版本,也用具有世界通用性.Gbk也是一种双字节编码,其实就是对中文简体的一种编码,不具有世界通