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开发面临的问题. 我们先来回忆一下 ...
随机推荐
- [转帖]阿里发布自研ARM服务器芯片倚天710,不对外出售
https://www.modb.pro/db/139440 10月19日,阿里巴巴旗下半导体公司平头哥发布自研云芯片倚天710,并宣称该芯片是业界性能最强的ARM服务器芯片,性能超过业界标杆20%, ...
- [转帖]shell脚本之awk命令——按列求平均值、最大值、最小值
文章目录 写在前面 awk求平均值 awk求最大值 awk求最小值 awk求极值.均值的实际应用 写在前面 awk命令求极值和均值需要熟悉该命令的基本用法,如果你不熟悉该命令,请先阅读shell脚本之 ...
- CPU实际频率查看
cat /sys/devices/system/cpu/cpu3/cpufreq/cpuinfo_cur_freq
- JVM 堆外内存查看方法
JVM 堆外内存查看方法 JVM 堆外内存查看方法 1.概述 是否曾经想过为什么Java应用程序通过众所周知的*-Xms和-Xmx调整标志消耗的内存比指定的数量大得多 ?由于各种原因和可能的优化,JV ...
- charles如何抓取https请求
我们都知道charles下载安装后只能抓取http请求,要想抓取https请求需要下载安装证书 下面介绍pc端和移动端的配置方法 一.pc端(win) 1.打开charles,点击help>SS ...
- 取消ts校验的注释
常用的有以下注释 单行忽略 // @ts-ignore 忽略全文:如果你使用这样,需要放在ts的最顶部哈. // @ts-nocheck 如下 <script lang="ts&quo ...
- Walrus 0.5发布:重构交互流程,打造开箱即用的部署体验
开源应用管理平台 Walrus 0.5 已于近日正式发布! Walrus 0.4 引入了全新应用模型,极大程度减少了重复的配置工作,并为研发团队屏蔽了云原生及基础设施的复杂度.Walrus 0.5 在 ...
- 9.3 Windows驱动开发:内核解析PE结构节表
在笔者上一篇文章<内核解析PE结构导出表>介绍了如何解析内存导出表结构,本章将继续延申实现解析PE结构的PE头,PE节表等数据,总体而言内核中解析PE结构与应用层没什么不同,在上一篇文章中 ...
- 8.4 ProcessHeap
ProcessHeap 是Windows进程的默认堆,每个进程都有一个默认的堆,用于在进程地址空间中分配内存空间.默认情况下ProcessHeap由内核进行初始化,该堆中存在一个未公开的属性,它被设置 ...
- C# 语言程序设计笔记
C#是一种最新的.面向对象的编程语言.它使得程序员可以快速地编写各种基于Microsoft .NET平台的应用程序,Microsoft .NET提供了一系列的工具和服务来最大程度地开发利用计算与通讯领 ...