问题

C语言中汉字如何存储?梳理思路!

答案

在计算机中,一个英文字符占1个字节,汉字占两个字节,如果用char字符数组存储字符时,需要在最后面自动加上一个字节的结束符“\0”

汉字转进制输出

比如:

    //英文字符,占4个字节
char Info[] = "abc";
printf("%s\n",Info);
printf("Info长度:%d\n",sizeof(Info)); //中文,占5个字节
char Han[]="中国";
printf("%s\n",Han);
printf("Han长度:%d\n",sizeof(Han));

不同的编码方式,汉字存储的字节数量不同,比如:

GB2312编码:一个汉字两个字节

UTF-8编码: 一个汉字三个字节

GBK编码:一个汉字两个字节

UTF-16:一个汉字3个字节

GB2312 --> GBK --> GB18030 是中文编码的三套方案,出现的时间从早到晚,收录的字符数目依次增加,并且向下兼容。GB2312 和 GBK 收录的字符数目较少,用 1~2个字节存储;GB18030 收录的字符最多,用1、2、4 个字节存储。
1) 从整体上讲,GB2312 和 GBK 的编码方式一致,具体为:

  • 对于 ASCII 字符,使用一个字节存储,并且该字节的最高位是 0,这和 ASCII 编码是一致的,所以说 GB2312 完全兼容 ASCII。
  • 对于中国的字符,使用两个字节存储,并且规定每个字节的最高位都是 1。

例如对于字母A,它在内存中存储为 01000001;对于汉字中,它在内存中存储为 11010110  11010000。由于单字节和双字节的最高位不一样,所以字符处理软件很容易区分一个字符到底用了几个字节。
2) GB18030 为了容纳更多的字符,并且要区分两个字节和四个字节,所以修改了编码方案,具体为:

  • 对于 ASCII 字符,使用一个字节存储,并且该字节的最高位是 0,这和 ASCII、GB2312、GBK 编码是一致的。
  • 对于常用的中文字符,使用两个字节存储,并且规定第一个字节的最高位是 1,第二个字节的高位最多只能有一个连续的 0(第二个字节的最高位可以是 1 也可以是 0,但是当它是 0 时,次高位就不能是 0 了)。注意对比 GB2312 和 GBK,它们要求两个字节的最高位为都必须为 1。
  • 对于罕见的字符,使用四个字节存储,并且规定第一个和第三个字节的最高位是 1,第二个和第四个字节的高位必须有两个连续的 0。

例如对于字母A,它在内存中存储为 01000001;对于汉字中,它在内存中存储为 11010110  11010000;对于藏文གྱུ,它在内存中的存储为 10000001  00110010  11101111  00110000。

字符处理软件在处理文本时,从左往右依次扫描每个字节:

  • 如果遇到的字节的最高位是 0,那么就会断定该字符只占用了一个字节;
  • 如果遇到的字节的最高位是 1,那么该字符可能占用了两个字节,也可能占用了四个字节,不能妄下断论,所以还要继续往后扫描:
    • 如果第二个字节的高位有两个连续的 0,那么就会断定该字符占用了四个字节;
    • 如果第二个字节的高位没有连续的 0,那么就会断定该字符占用了两个字节。

可见,当字符占用两个或者四个字节时,GB18030 编码要检测两次,处理效率比 GB2312 和 GBK 都低。

GBK 于 1995 年发布,这一年也是互联网爆发的元年,国人使用电脑越来越多,也许是 GBK 这头猪正好站在风口上,它就飞起来了,后来的中文版 Windows 都将 GBK 作为默认的中文编码方案。
注意,这里我说 GBK 是默认的中文编码方案,并没有说 Windows 默认支持 GBK。Windows 在内核层面使用的是 Unicode 字符集(严格来说是 UTF-16 编码),但是它也给用户留出了选择的余地,如果用户不希望使用 Unicode,而是希望使用中文编码方案,那么这个时候 Windows 默认使用 GBK(当然,你可以选择使用 GB2312 或者 GB18030,不过一般没有这个必要)。

汉字编码输出

汉字编码并输出示例:

    //汉字编码
unsigned char Han[]="中国";
printf("汉字:%s\n",Han);
printf("十六进制:");
for(int i=0;i<4;i++)
{
printf("%X",Han[i]);
}
printf("\n十进制:");
for(int i=0;i<4;i++)
{
printf("%d",Han[i]);
}

汉字编码输出存储

汉字编码存储示例:

	//汉字编码存储
unsigned char Han[] = "中国";
FILE* fp = fopen("out.txt", "w");//输出
printf("汉字:%s\n", Han);
fputs("十六进制:", fp);
for (int i = 0; i < 4; i++)
{
fprintf(fp, "%X", Han[i]);
}
fseek(fp, 0, SEEK_END);
fputs("\n十进制:", fp);
for (int i = 0; i < 4; i++)
{
fprintf(fp, "%d", Han[i]);
}
fclose(fp);

参考

1、汉字的存储

2、使用数组来储存中文(字符串)

3、C语言:GB2312编码和GBK编码,将中文存储到计算机

4、C语言/C++字符编码方式解析

C:汉字存储的更多相关文章

  1. mysql 编码和汉字存储占用字节问题的探索

    MySql 5.5 之前,UTF8 编码只支持1-3个字节,只支持BMP这部分的unicode编码区,BMP是从哪到哪?基本就是 0000 ~ FFFF 这一区. 从MySQL 5.5 开始,可支持4 ...

  2. Oracle字符编码与汉字存储长度的处理

    执行如下语句,查看汉字在数据库中所占的字节: select vsize('汉') from dual; 一般情况下,得到的结果大部分为值:2 或 3 一般linux下安装oracle数据库,默认字符编 ...

  3. Oracle 汉字在不同字符集下所占字节

    今天发现了一个问题,一个长度设置为2000字节的字段,插入一条长度为1000的汉字数据,竟然报错了. 一个汉字占两个字节,按理说刚好是2000个字节.但通过查看日志,发现插入数据的长度为3000字节. ...

  4. VB6单片机编程中的汉字处理

    在DOS时代,拥有一个华丽的汉字菜单几乎是每个高档中文应用程序必须的包装.中文Windows操作系统的出现使得高级开发平台实现全中文的提示和界面非常容易和方便.在一般的应用程序中已经很少需要去专门考虑 ...

  5. java中文乱码解决之道(二)-----字符编码详解:基础知识 + ASCII + GB**

    在上篇博文(java中文乱码解决之道(一)-----认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述字符集.字符编码等基础知识和ASCII.GB的详情. 一.基 ...

  6. HTML基础笔记-02

    ---恢复内容开始--- 学习网站:W3School 一.HTML的认识 纯文本语言:只显示内容,不显示样式,也不能描述语义的文档,但是也不会乱码 语义:数据的含义就是语义,数据是符号,在这表示标签 ...

  7. C#编程总结(九)字符编码

    C#编程总结(九)字符编码 相信大家一定遇到过乱码的问题,为什么会乱码呢?输出的数据怎么就跟输入的不一样呢? 最近在总结加密问题,也遇到了同样的困扰.所以今天来集中解决这个问题. 什么是字符? 字符是 ...

  8. WGZX:javaScript 学习心得--2

    转贴javascript心得(二) 标签: javascriptajaxweb开发htmlfirefox框架 2008-09-11 10:56 636人阅读 评论(0) 收藏 举报  分类: UI(2 ...

  9. java中几种常见字符集与乱码介绍

    1.  ASCII和Ansi编码 字符内码(charcter code)指的是用来代表字符的内码 .读者在输入和存储文档时都要使用内码,内码分为  单字节内码 -- Single-Byte chara ...

随机推荐

  1. NVIDIA GPU上的直接线性求解器

    NVIDIA GPU上的直接线性求解器 NVIDIA cuSOLVER库提供了密集且稀疏的直接线性求解器和本征求解器的集合,它们为计算机视觉,CFD,计算化学和线性优化应用程序提供了显着的加速.cuS ...

  2. 面试官:说一下JVM常用垃圾回收器的特点、优劣势、使用场景和参数设置

    今天去看牙医,他问我年级轻轻牙齿怎么磨损这么严重?我说,没有人点赞的这些年,我都是咬着牙过来的. Java中的垃圾回收器几乎是面试中的必考点,无论是面试初级,中级还是高级,总免不了要问一问垃圾回收器的 ...

  3. 小程序微信支付(UNIAPP+第三方SDK:binarywang)

    小程序支付流程图说明(UNIAPP+第三方SDK:binarywang) 说明:小程序为UNI-APP开发,使用的第三方微信支付SDK为binarywang提供的,此SDK对微信公众号.小程序.微信各 ...

  4. laya fgui 超简单的UI框架

    FairyGUI 超简单的UI框架 Laya使用fgui的超简单UI框架 使用场景:用于使用fgui进行layaUI开发的程序人员 整个框架分为3个模块,共有4个类: FGUIManager :FGU ...

  5. 深入理解Spring的两大特征(IOC和AOP)

    一.spring 的优点? 1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 2.可以使用容易提供的众多服务,如事务管理,消息服务等 3.容器提供单例模式支持 4.容器提供了AOP技术,利用它很 ...

  6. NOIP模拟测试24「star way to hevaen·lost my music」

    star way to heaven 题解 大致尝试了一下并查集,记忆化搜索,最小生成树 最小生成树是正解,跑最小生成树然后找到最大的值 欧几里德距离最小生成树学习 prim楞跑 至于为什么跑最小生成 ...

  7. leetcode1141 N*3矩阵。阿里笔试no.1

    你有一个 n x 3 的网格图 grid ,你需要用 红,黄,绿 三种颜色之一给每一个格子上色,且确保相邻格子颜色不同(也就是有相同水平边或者垂直边的格子颜色不同). 给你网格图的行数 n . 请你返 ...

  8. Project Reactor 响应式编程

    目录 一. 什么是响应式编程? 二. Project Reactor介绍 三. Reactor核心概念 Flux 1. just() 2. fromArray(),fromIterable()和 fr ...

  9. [源码解析] 深度学习分布式训练框架 horovod (8) --- on spark

    [源码解析] 深度学习分布式训练框架 horovod (8) --- on spark 目录 [源码解析] 深度学习分布式训练框架 horovod (8) --- on spark 0x00 摘要 0 ...

  10. 利用 V8 深入理解 JavaScript 设计

    JavaScript 代码运行 以大家开发常用的 chrome 浏览器或 Node 举例,我们的 JavaScript 代码是通过 V8 运行的.但 V8 是怎么执行代码的呢?当我们输入 const ...