UTF-8 的理解
举个简单的例子:
Unicode 只是一个业界标准,具体一个字符占多少字节,取决于编码方式,包括 UTF-8 UTF-16 GB2312 等
“汉” 在 UTF-8 中占到 3 个字节,即 E6 B1 89
在 GB2312 中占到 2 个字节,即 BA BA,一般我们的电脑都是以 GB2312 编码中文的
注意:如果以 VS 编译器以 Unicode 编码,则是 0x6C49,同样占 2 个字节,多字节则是 BA BA
wchar_t aaa[] = L"汉"; // 0x6c49 数组占 4 个字节,包括占两个字节的 '\0' char bbb[] = "汉"; // 0xBABA 数组占 3 个字节,包括占一个字节的 '\0'

在 UTF-16 中占到 2 个字节,即 0x6C49
UTF-16 LE是windows上默认的Unicode编码方式,使用wchar_t表示。所有wchar_t *类型的字符串(包括硬编码在.h/.cpp里的字符串字面值),VC都自动采用UTF-16的编码(字符串字面值,literal string,存在很多坑。特别是char *类型的字面值,最终内存使用何种编码方式完全取决于当前文件的编码方式。也就是说当前文件如果是GBK编码的,那么文件里char * str = "中午",str指向的内存字符串二进制是使用GBK编码的。如果文件编码是UTF-8,那么内存是使用UTF-8编码。所以为什么一直要强调字符串应该放在资源文件里,而不是硬编码在.h/.cpp文件里!)。
使用 UTF-8 的优势,没有字节序的概念,特别适合用于字符串的网络数据传输,不用考虑大小端问题。对于非英文网页(对于我们而言,简单说东亚文字网页),能够避免各种乱码问题。
相关链接:
补充:
ANSI 编码是各个国家不同语种下的字符编码,其字符的编码值只在该语种中有效,不是全球统一编码的,比如中文的 GB2312 编码就是简体中文的 ANSI 编码。
Unicode 编码则是全球统一的双字节编码,所有语种的字符在一起统一的编码,每个字符的编码都是全球唯一的。
UTF8 编码是一种可变长的宽字节编码,也是一种全球统一的字符编码。
对于大小写英文字母和数字的 ANSI 编码,是字符 ASCII 码,英文字母和数字的 ACSII 码是全球统一的,比如大写字母 A 的 ASCII 码是 65(十六进制是 41H),数字 0 的A SCII 码是 48(十六进制是 30H)。所以在所有语种中,大小写字母及数字的 ANSI 编码,都是能识别的。不同语种下的本地文字字符,一般是不能相互识别的。
使用中文 ANSI 编码的字符串开发的程序(代码中使用的都是中文字符串,使用的是 ANSI 窄字节编码),拿到俄文操作系统中可能显示的都是乱码,因为在俄文的 ANSI 编码中只识别俄文的 ANSI 编码出来的字符串,无法识别中文 ANSI 编码的字符串。这里主要有两类字符乱码问题,一是 UI 界面上显示的文字是乱码;二是使用路径去创建文件或访问文件时会因为路径中的字符是乱码,导致文件创建或访问失败。
Windows 系统主要使用 Unicode 编码,Linux 则使用 UTF8 编码,后台服务器一般使用的都是 Linux 系统,而客户端是运行在 Windows 操作系统上的。一般客户端与服务器交互的数据的字符串编码统一使用全球统一编码的 UTF8 编码。
客户端收到 UTF8 编码的字符串后,需要将 UTF8 字符换转换后显示在界面上。如果客户端使用的是 Unicode 编码字符集,将 UTF8 编码的字符串转换成 Unicode 编码的字符串后再显示到界面上;如果客户端使用的是多字节 ANSI 编码,则需要再将 Unicode 编码的字符串转成 ANSI 编码的字符串。
这里注意一下,UTF8 编码的字符串要转成 ANSI 编码的,不能直接将 UTF8 转成 ANSI,需要先将 UTF8 转成 Unicode,然后再将 Unicode 转成ANSI。
现在的 Windows 程序基本都用 Unicode 字符编码了,工程属性中将字符集都设置成了 Unicode 字符集,代码中都使用 Unicode 编码的字符串。但是还有一些老的程序使用的还是 ANSI 窄字节的字符。那这些老的程序如何才能在外文的操作系统中正常运行呢?微软提供了一种兼容这些老程序的办法。
可以到 Windows 控制面板的区域语言设置中将非 Unicode 语言设置成程序中使用的字符语种即可
问题:为什么中文 ANSI 编码的程序在外文操作系统中会出现乱码?
解释:
程序中调用 API 函数 SetWindowTextA 给程序中的窗口设置文字或标题时,传入的字符串是 ANSI 窄字节编码的,而 SetWindowTextA 函数内部及底层的流程中会使用本地设置的 ANSI 字符集编码库将 ANSI 编码的字符串转成Unicode 编码的字符串后再设置到窗口中,最终界面上看到的文字是 Unicode 编码的文字。所以在将中文字符转换成 Unicode 时,如果使用的是本地设置的英文字符集编码进行转换,则会出现乱码;如果使用中文简体的字符集编码进行转换,则能正常显示。
所以,要让使用中文 ANSI 编码字符的程序能在英文操作系统中正常显示并运行,需要将英文操作系统中区域语言设置项中的“非 Unicode 程序的语言”设置成中文才行。
窄字节与宽字节的转换是调用 MultiByteToWideChar 和 WideCharToMultiByte 接口中的 CP_ACP 标记对应的本地 ANSI 字符集编码库
比如:如果将非 Unicode 语言设置成英语(美国),则使用英文的 ANSI 字符编码库;如果设置成中文简体,则使用中文简体的 ANSI 字符集编码库。
参考:一文带你弄懂C++中的ANSI、Unicode和UTF8三种字符编码
UTF-8 的理解的更多相关文章
- Unicode 字符和UTF编码的理解
Unicode 编码的由来 我们都知道,计算机的内部全部是由二进制数字0, 1 组成的, 那么计算机就没有办法保存我们的文字, 这怎么行呢? 于是美国人就想了一个办法(计算机是由美国人发明的),也把文 ...
- 从Java String实例来理解ANSI、Unicode、BMP、UTF等编码概念
转(http://www.codeceo.com/article/java-string-ansi-unicode-bmp-utf.html#0-tsina-1-10971-397232819ff9a ...
- 转载:谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词
转载: 谈谈Unicode编码,简要解释UCS.UTF.BMP.BOM等名词 这是一篇程序员写给程序员的趣味读物.所谓趣味是指可以比较轻松地了解一些原来不清楚的概念,增进知识,类似于打RPG游戏的升级 ...
- MQTT V3.1--我的理解
最近因为工作需要,需要对推送消息了解,因此对MQTT进行了整理,这里更多的是对MQTT英文版的翻译和理解. MQTT(Message Queue Telemetry Transport),遥测传输协议 ...
- java 乱码详解_jsp中pageEncoding、charset=UTF -8"、request.setCharacterEncoding("UTF-8")
http://blog.csdn.net/qinysong/article/details/1179480 java 乱码详解__jsp中pageEncoding.charset=UTF -8&quo ...
- uboot: 理解uboot要看哪些书
概览:
- python3中的编码与解码(超好理解)
编码和解码是针对数据而言的,数据能干什么呢?无非就是用来显示,储存和传输的: 储存和传输数据当然是希望数据越小越好,所以发明了utf-8这种数据编码显示:它智能将英文用一个字节表示,欧洲的字符用两个字 ...
- Java中char和String 的深入理解 - 字符编码
开篇 https://blog.csdn.net/weixin_37703598/article/details/80679376 我们并不是在写代码,我们只是将自己的思想通过代码表达出来! 1 将思 ...
- 编码(2)从字节理解Unicode(UTF8/UTF16)
https://www.cnblogs.com/zizifn/p/4716712.html 从字节理解Unicode(UTF8/UTF16) 如果你不知道或者不了解什么是Unicode/UTF8/UT ...
- JavaScript大杂烩12 - 理解Ajax
AJAX缘由 再次谈起这个话题,我深深的记得就在前几年,AJAX被炒的如火如荼,就好像不懂AJAX,就不会Web开发一样.要理解AJAX为什么会出现,就要先了解Web开发面临的问题. 我们先来回忆一下 ...
随机推荐
- [转帖]疑问:进程在竞争CPU时并没有真正运行,为什么还会导致系统的负载升高?
疑问:进程在竞争CPU时并没有真正运行,为什么还会导致系统的负载升高? 因为存在CPU上下文切换. linux系统说明 Linux是一个多任务操作系统,它支持远大于CPU数量的任务同时运行.当然,这些 ...
- [转帖]overcommit_memory、overcommit_ratio、CommitLimit、Committed_AS概念
overcommit_memory.overcommit_ratio.CommitLimit.Committed_AS概念 overcommit_memory是一个内核对内存分配的一种策略. over ...
- [转帖]SystemStap、BCC、bpftrace
https://plantegg.github.io/2019/09/16/SystemStap/ Linux 4.4+ 支持 eBPF.基于 eBPF 可以将任何内核函数调用转换成可带任何 数据的用 ...
- Find -mtime 的图解
- 【windows Server 2019系列】 构建IIS服务器
个人名片: 对人间的热爱与歌颂,可抵岁月冗长 Github:念舒_C.ying CSDN主页️:念舒_C.ying 个人博客 :念舒_C.ying Web服务器也称为WWW(World Wide W ...
- 有道云笔记之备选方案Obsidian和Notion
有道云笔记限制登录设备 在商业项目中一般都会有plana.planb,对于云笔记,我也在寻找planb,有道云笔记在国内市场已经占据了很大的份额. 同类型中的就不再去挑选了,我觉得商业软件,迟早也会走 ...
- 物联网浏览器(IoTBrowser)-电子秤模块及二次驱动开发
本章介绍电子秤模块的示例功能以及二次开发称重驱动的代码,二次开发以顶尖OS2型号驱动为示例,实现方式与物联网浏览器(IoTBrowser)-顶尖OS2电子秤协议实现类似,不同的是电子秤只需要采集重量不 ...
- 【一】分布式训练---单机多卡多机多卡(飞桨paddle1.8)
1.分布式训练简介 分布式训练的核心目的: 加快模型的训练速度.通过对训练任务按照一定方法拆分分配到多个计算节点进行计算,再按照一定的方法对需要汇总的信息进行聚合,从而实现加快训练速度的目的. 1.1 ...
- 使用 arxiv-sanity &paperwithcode 跟进最新研究领域的文章
1.arxiv-sanity介绍 arxiv.org是一个非常大的预印本资源库,里面有大量的最新的论文,但缺点是浏览.搜索和排序不是很方便.这个资源库每天会更新大量的论文,如果通过手动搜索和浏览则效率 ...
- 中兴BE7200Pro+的WIFI 7路由器开箱
上一个讨论的帖子:https://www.chiphell.com/thread-2573626-1-1.html . 对应小米WIFI 7路由器BE6500 Pro开箱的帖子:https://www ...