字符编码与C++

2023-11-09

背景: C++的项目,字符编码是一个大坑,不同平台之间的编码往往不一样,如果不同编码格式用一套字符读取格式读取就会出现乱码。 所以本文旨在对字符编码的知识做一个大概的梳理。

字符编码定义

计算机是以二进制的形式来存储数据的,它只认识 0 和 1 两个数字。我们在屏幕上看到的文字,在存储之前都被转换成了二进制(0和1序列),在显示时也要根据二进制找到对应的字符, 所以特定的文字必然对应着固定的二进制 。

那怎样将文字与二进制对应起来呢 ? 这就需要有一套规范,计算机公司和软件开发者都必须遵守,这样的一套规范就称为字符集(Character Set)或者字符编码(Character Encoding)

严格来说,字符集和字符编码不是一个概念,字符集定义了文字和二进制的对应关系,为字符分配了唯一的编号,而字符编码规定了如何将文字的编号存储到计算机中。我们暂时先不讨论这些细节,姑且认为它们是一个概念

各种字符编码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JXfyJUgE-1644907769659)(C:\Users\86157\AppData\Roaming\Typora\typora-user-images\1644906042899.png)]

  • ASCII码

    计算机是美国人发明的,他们首先要考虑的问题是,如何将二进制和英文字母对应起来,所以ASCII码由此诞生。 ASCII包括128个字符,包含了英⽂字⺟的大小写以及⼀些其他控制符。

  • GBK编码

    计算机是美国人发明的,它使用的是 ASCII 编码,只能显示英文字符,对汉语、韩语、日语、法语、德语等其它国家的字符无能为力。

    为了让本国公民也能使用上计算机,各个国家(地区)也开始效仿 ASCII,开发了自己的字符编码。中文编码也随即出现: GB2312 -->GBK --> GB18030是中文编码的三套方案,出现的时间从早到晚,收录的字符数目依次增加,并且向下兼容。

  • Unicode

    世界各国家都根据自己的语言文化开发了不同的字符编码,不具有通用性,在一种编码下开发的软件或者编写的文档,拿到另一种编码下就会失效,必须提前使用程序转码,非常麻烦。 人们迫切希望有一种编码能够统一世界各地的字符,计算机只要安装了这一种字编码,就能支持使用世界上所有的文字。

    在这种呼吁下,Unicode 诞生了。Unicode 也称为统一码、万国码 。 看名字就知道,Unicode 希望统一所有国家的字符编码。但Unicode 也只定义了符号的⼆进制表示,没有规定如何存储。 UTF-8UTF-16UTF-32 是基于Unicode的具体存储⽅式。

    • UTF-8:一种变长的编码方案,使用 1~6 个字节来存储;
    • UTF-32:一种固定长度的编码方案,不管字符编号大小,始终使用 4 个字节来存储;
    • UTF-16:介于 UTF-8UTF-32 之间,使用 2 个或者 4 个字节来存储,长度既固定又可变。

    这三种方式的优缺点:

    • UTF-8使用尽量少的字节来存储一个字符,不但能够节省存储空间,而且在网络传输时也能节省流量,所以很多纯文本类型的文件(例如各种编程语言的源文件、各种日志文件和配置文件等)以及绝大多数的网页(例如百度、新浪、163等)都采用UTF-8编码。

      UTF-8 的缺点是效率低,不但在存储和读取时都要经过转换,而且在处理字符串时也非常麻烦。

    • UTF-32 是“以空间换效率”,正好弥补了UTF-8的缺点,UTF-32 的优势就是效率高:UTF-32 在存储和读取字符时不需要任何转换,在处理字符串时也能最快速地定位字符。

      UTF-32 的缺点也很明显,就是太占用存储空间了,在网络传输时也会消耗很多流量。

    • UTF-16可以看做是 UTF-8UTF-32的折中方案,它平衡了存储空间和处理效率的矛盾。对于常用的字符,用两个字节存储足以,这个时候 UTF-16是不需要转换的,直接存储字符的编码值即可。

宽字符与窄字符

  • 有的编码方式采用 1~n 个字节存储,是变长的,例如 UTF-8GB2312GBK 等;如果一个字符使用了这种编码方式,我们就将它称为多字节字符,或者窄字符
  • 有的编码方式是固定长度的,不管字符编号大小,始终采用 n 个字节存储,例如 UTF-32UTF-16 等;如果一个字符使用了这种编码方式,我们就将它称为宽字符
  • Unicode 字符集可以使用窄字符的方式存储,也可以使用宽字符的方式存储;GB2312GBKShift-JIS 等国家编码一般都使用窄字符的方式存储;ASCII 只有一个字节,无所谓窄字符和宽字符。

Visual C++6.0用的是多字节编码;

Virtual Studio 2010 默认使用的是Unicode编码。

MFC有两种编码方式,Unicode和多字节并且可以设置切换。切换方法是打开项目属性页,常规项对应的字符集中可切换编码方式。

c/c++中的字符与字符串

  • Windows使用两种字符集ANSI和UNICODE,前者就是通常使用的单字节方式,但这种方式处理象中文这样的双字节字符不方便,容易出现半个汉字的情况。而后者是双字节方式,方便处理双字节字符。

  • 在Visual Studio中编写C++代码时,该如何指定字符串的编码呢?其实很简单,使用双引号括住的字符串,使用的就是ANSI窄字节编码;使用L+双引号括住的字符串,使用的就是Unicode宽字节编码

    char* pStr = "This is a Test.";    // ANSI编码
    WCHAR* pWStr = L"This is a Test."; // Unicode宽字节编码
    

    也可以使用**_T宏**定义来指定字符串的编码格式: _T 是一个宏,如果项目使用了Unicode字符集,则自动在字符串前面加上L,否则字符串不变。因此用_T来保证兼容性。

    TCHAR* pStr = _T("This is a Test.");
    

    也可以在属性页设置字符集:右键项目->配置属性->常规->字符集

  • c/c++中的字符与字符串

    • C/C++语言中的字符类型:存在两种表示字符的基本类型:

      • char: 也叫 窄字符 (多字节字符),一个char占一个字节, 使用 ASCII 。
      • wchar_t: 也叫宽字符字符,一个wchar_t占2个字节或者4个字节,满足国际化应用开发的需求,使用Unicode 字符集(UTF-16 或者UTF-32 编码 )。
    • 对应两种字符类型存在两种字符串类型(C++):

      • string:char字符列表或者是字节列表
      • wstringwchar_t字符列表或者是宽子节列表
    • 字符串常量,C++11标准中增加了一些表示字符串常量的标识,如下有:

      • L"您好!": wstring字符串常量,使用文件保存编码方式字符集;会将ANSI字符串转换成Unicode的字符串,就是每个字符占用两个字节。
      • R"(您 好 \n)": 原始字符串常量, 原始字面量很容易理解即不进行转义的完整字符串,保留所有的字符。
      • u8“您好!”: string字符串常量(字节数组),使用UTF8进行编码保存。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

字符编码与C++ 的相关文章

随机推荐

  • xml中使用include引入布局

    为了复用布局 使用include方式引用 activity top bar xml 代码如下 需要注意的是 父容器LinearLayout中layout height为wrap content 而不是match parent 以免引入到其他
  • 如何动态创建二维数组[cpp]

    我们常见的用new来 动态创建一维数组 int m std cin gt gt m int 数组名 new int m 动态创建二维数组 方法一 int n 地图的长宽 cin gt gt n int map new int n 创建一个指
  • js 实现颜色值格式转换 rgb和十六进制的转换

    本文章是以prototype原型的方式 给string字符串类型添加方法 用于实现颜色值格式的转换 如果你不用原型方法 那么你只要借鉴实现方法就好了 RGB转换为16进制 String prototype colorHex function
  • Lightgbm多余信息显示

    LightGBM Warning No further splits with positive gain best gain inf 设置参数 verbosity 1 或 verbose 1
  • Python安装教程(2023年,3月)

    一 Python下载 1 进入Python官网 官网地址 https www python org 2 点击 Downloads 展开后点击 Windows 跳转到下载python版本页面 选择 Stable Releases 稳定版本 我
  • [gfirefly深入解析]--总体架构及demo讲解

    gfirefly是开源的分布式游戏服务器端框架 是firefly的gevent版本 想了解更多关于firefly可参考http www oschina net question 947559 147468 这是firefly的官网http
  • 【读书笔记】《Web全栈工程师的自我修养》

    读书笔记 Web全栈工程师的自我修养 推荐书单 1 什么是全栈工程师 黑客与画家 专业主义 2 如何成为全栈工程师 重来 更为简单有效的商业思维 精益创业 3 从学生到工程师 编程之美 微软技术面试心得 4 野生程序员的故事 打造Faceb
  • TOP命令及参数解析

    Top命令是linux 下常用的系统性能分析工具 能够实时显示系统中各个进程的资源占用状况 类似于windows的任务管理器 下面详细介绍它的使用方法 top 可以显示当前系统正在执行的进程的相关信息 包括进程ID 内存占用率 CPU占用率
  • 机器学习-分类-线性分类器

    在一个机器学习任务中 如果每一条数据的目标值是离散的 则该任务是一个分类任务 解决分类问题基本的方法有 线性分类器 决策树 朴素贝叶斯 人工神经网络 K近邻 KNN 支持向量机 SVM 组合基本分类器的集成学习算法 随机森林 Adaboos
  • java中float和double型数据在赋值时有哪些注意事项?,java语言中float和double类型的数据在编程时的注意事项...

    float和double类型的数据在编程时的需要注意的地方 package execisetest public class AccuranceTest public static void main String args float a
  • Rsync命令使用

    Rsync优点 持增量备份 第 次全量备份 第 次增量备份 边复制 边 较 边统计 传输效率很 数据集中备份 客户端可以推送数据 服务端 也可以从服务端获取数据 以客户端为参照物 保持 件属性 符号链接 硬链接 权限 时间等 安全 式传输
  • 微信企业号回调模式配置详细讲解

    对于微信企业号 我相信很多人都不陌生了 今天跟大家一起来探讨一下用java怎么去实现微信企业号回调模式配置 为什么需要开启回调模式 对于这点 我相信官方文档中说得比我更清楚 但是我还是想大家熟悉一下什么是回调模式 说白了就是当你有一个属于自
  • mysql in 查询时 入参为逗号隔开的字符如何查询,使用 find_in_set 代替 in

    SELECT FROM lao car model where find in set id 101 102 41840930066432 find in set 函数中 id 查询的字段名
  • 传统支付方式不能满足线下支付的需求

    刷脸支付趋势现在可以在便利店 餐饮店看见这样的场合 收银台不见了 换成了一块类似平板大小的显示屏 上边标注了刷脸支付 消费者在屏幕上点击开启刷脸支付 将脸部对准摄像头 摄像头采集到消费者面部信息后即可完成支付 消费金额就直接从消费者账户中扣
  • epoll实现原理

    用户态协议栈 为什么要实现epoll epoll并不是协议栈里面的 为什么要实现用户态协议栈 因为内核的epoll是对内核文件系统vfs fd进行的管理 是跟内核协议栈一起使用的 内核协议栈处理io后通过回调的方式来操作epoll中的就绪队
  • 两台计算机直连通信过程,教大家两台电脑网线直连传输的技巧

    我们总有需要把一台电脑的资料传输到另一台电脑的时候 其实我们可以让两台电脑共享局域网 通过网线直连来达到传输的目的 下面来看看小编是怎么操作的吧 1 设置电脑IP 首先打开下图界面 点击本地连接 2 接着我们点击属性选项 3 点击下图选中的
  • 零基础前端Vue的小白学习路——(Node.js,VSCODE,Hbuilder X)环境搭建

    俗话说 实践是检验真理的唯一标准 IT的学习更是离不开实践 要想成绩好 一个 做题笔记本 少不了 搭建环境想必是许多IT人刚入门一个新语言的第一个门槛 不正确的配置 不适配的版本往往会让你未来的道路变得不平坦 因此搭建环境时需要尤为谨慎 好
  • AVL代码 java

    任意一个节点 左右字数的高度差不能为超过1 先对x左旋转 转化为LL import java util ArrayList public class AVLTree
  • Java-静态绑定和动态绑定

    Java 静态绑定和动态绑定 绑定的概念 静态绑定 动态绑定 举例 绑定的概念 绑定指的是一个方法的调用与方法所在的类 方法主体 关联起来 对java来说 绑定分为静态绑定和动态绑定 或者叫做前期绑定和后期绑定 静态绑定 概念 在程序执行前
  • 字符编码与C++

    背景 C 的项目 字符编码是一个大坑 不同平台之间的编码往往不一样 如果不同编码格式用一套字符读取格式读取就会出现乱码 所以本文旨在对字符编码的知识做一个大概的梳理 字符编码定义 计算机是以二进制的形式来存储数据的 它只认识 0 和 1 两