当前位置: 首页 > news >正文

C#与C++交互(2)——ANSI、UTF8、Unicode文本编码

【前言】

我们知道计算机上只会存储二进制的数据,无论文本、图片、音频、视频等,当我们将其保存在计算机上时,都会被转成二进制的。我们打开查看的时候,二进制数据又被转成我们看得懂的信息。如何将计算机上的二进制数据转为我们看得懂的文本、图片等,就涉及到编码规则,即二进制数据与我们看的懂的信息之间的映射关系。我们这里讨论的是文本编码规则,有ANSI、ASCII、UTF-8、Unicode等。

【ASCII】

ASCII是编程首先会接触到的,其全名是American Standard Code for Information Interchange, 叫做“美国信息交换标准码”。现代计算机技术是从英文国家兴起的,最初的文本的内容只涉及26个英文、10个数字,一些行业常用字符等,加起来凑一凑到了128个。128个字符的集合就是ASCII字符集。128个在二进制中就需要7bit来区分。但计算机中最低要一个字节,即8bit。因此ASCII的最高位为0,空着不用。ASCII码中,一个英文字母占一个字节的空间。

ASCII码图- sunsky303 - 博客园

 【ANSI】

随着计算机发展到其他国家,各个国家也需要有各自的字符集,在创建自己国家语言的字符集时必须要兼容已有的ASCII字符集。

有些国家的语言字符很少,不到128个,例如拉丁文,就直接把ASCII编码中没用到的最高位用上。

但对汉字来说,常用汉字有六千多个,再加上中文相关的图形字符等,这就需要两个字节来表示。

两个字节最多可以存储的字符数目是2的16次方,即65536个字符,足够其他语言使用了。同样的,对于韩文、日文也需要两个字节表示。

对于ASCII字符集中的字符仍然用一个字节表示,对于其他语言的字符用两个字节表示。例如在中文的GB2312的表示中,如果一个字节的最高位为0,表示这个字节是ASCII编码,如果最高位为1,那么表示其是双字节编码的首字节,与后面的一个字节一块进行编码。这就是ANSI字符集,其是对ASCII字符集的拓展。

在中文操作系统下,ANSI字符集的编码规则是GB2312;在日文操作系统下,编码规则是JIS。

GB2312编码中只收集了常用的汉字,没有生僻字,后来的GBK和GB18030收集了更多的字符。

【Unicode】

Ansi字符集的问题是如果一个文本是GBK编码的,那么在日文操作系统上无法正确显示中文,看到的会是乱码。因此,需要一个包含所有国家所有字符的字符集,这个字符集就是Unicode字符集。

其目前已经包括了十多万个字符,还在不断增加中。此时用3个字节建立映射关系就够了,但是计算机中没有24位的数字类型,所有还是要用4个字节来表示。

在Unicode中所有字符都用4个字节表示,UTF-32编码刚好用4个字节表示。

UTF-16编码是变长编码,前65536个字符用两个字节表示,其他字符用四个字节表示。通过判断一个字节的前几位是否为“11011”来区分一个字符使用两个字节,还是四个字节表示。

对于英文字母来说,其由最初的一个字节变成了UTF-32编码的4个字节和UTF-16编码的两个字节,还是存在空间浪费,采用UTF-8编码可以有效节省空间,其也是变长编码。

如果读取的一个字节的首位为0,表示这个字节有个对应的字符;如果读取的一个字节的首位为1,接着判断下一个bit,依次判断得到的结果为110,那么表示这个字节和解析来的字节一起有个对应的字符。依次类推,首个字节中前几位为1110,表示3个字节对应一个字符,11110表示4个字节对应一个字符,如下图所示。

【其他】

一般来说UTF-8应用是最广泛的。在C#中,文本默认是UTF-16编码,一个字符对应两个字节。(一个字符对应四个字节的情况在中英文语况很少遇到)。而在C++中默认是ANSI编码的。

从C++传递字符串给C#,如果字符串全是英文,可以直接传给C#,因为UTF-16兼容ANSI中的英文编码。如果是字符串中包含有中文,则在C#端就无法正确识别。需要先将字符串转成字节序列(即字节数组),再将ANSI字节序列转成Unicode字节序列,再将Unicode字节序列转成UTF-16或UTF-8编码的字符串。

注意,代码文件也是文本文件,也会有编码格式的问题,在VS中选择文件->高级保存选项可以修改代码文件的编码格式。

【参考】

ASCII码和ANSI码的区别_ansi ascii_斑驳的岁月的博客-CSDN博客

程序员必备:彻底弄懂常见的7种中文字符编码 - 知乎 (zhihu.com)

Unicode 编码及 UTF-32, UTF-16 和 UTF-8 - 知乎

http://www.lryc.cn/news/119250.html

相关文章:

  • SQLSTATE[42000]: this is incompatible with sql_mode=only_full_group_by in
  • 企业权限管理(五)-订单分页
  • Blender如何给fbx模型添加材质贴图并导出带有材质贴图的模型
  • MySQL不走索引的情况分析
  • 安装ubuntu22.04系统,配置国内源以及ssh远程登录
  • win10 安装ubuntu子系统并安装宝塔
  • gazebo 导入从blender导出的dae等文件
  • 目标检测YOLOv3基于DarkNet53模型测试-笔记
  • Unity项目中查找所有使用某一张图片的材质球,再查找所有使用材质球的预设
  • postman接口测试中文汉化教程
  • java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver的解决办法
  • 认识所有权
  • 恒盛策略:怎样看k线图实图详解如何看懂k线图?
  • 物联网的定义、原理、示例、未来
  • Vue 整合 Element UI 、路由嵌套和参数传递(五)
  • Git全栈体系(四)
  • 数据结构初阶--二叉树的链式结构
  • Taro UI中的AtTabs
  • ChatGPT FAQ指南
  • 在矩池云使用ChatGLM-6B ChatGLM2-6B
  • 7.2 手撕VGG11模型 使用Fashion_mnist数据训练VGG
  • docker安装ES
  • python爬虫实战(2)--爬取某博热搜数据
  • k8s的Namespace详解
  • 【Redis】Redis内存过期策略和内存淘汰策略
  • 技术干货 | cilium 原理之sock_connect
  • K8S之Pod详解与进阶
  • 【小曾同学赠书活动】开始啦—〖测试设计思想〗
  • 【Docker晋升记】No.1--- Docker工具核心组件构成(镜像、容器、仓库)及性能属性
  • ROBOGUIDE教程:FANUC机器人X型焊枪气动点焊焊接