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开发面临的问题. 我们先来回忆一下 ...
随机推荐
- [转帖]tcp、http和socket的区别
https://www.jianshu.com/p/88d69454bdde 一:tcp协议 tcp协议属于传输层协议(UDP也属于传输层协议,但是UDP协议是无状态的).建立一个TCP连接需要三次握 ...
- [转帖]Oracle参数解析(parallel_force_local)
https://www.modb.pro/db/122032 是否需要增加这个参数? 往期专题请查看www.zhaibibei.cn这是一个坚持Oracle,Python,MySQL原创内容的公众号 ...
- [转帖]正则表达式及在Jmeter中的应用
目录 1.正则表达式 1.1 什么是正则表达式 1.2 为什么使用正则表达式 2.语法 2.1 普通字符 2.2 限定符 2.3 非打印字符 2.4 特殊字符 2.5 定位符 2.6 修饰符(标记) ...
- [转帖]Elasticsearch 技术分析(七): Elasticsearch 的性能优化
https://www.cnblogs.com/jajian/p/10176604.html 硬件选择# Elasticsearch(后文简称 ES)的基础是 Lucene,所有的索引和文档数据是存储 ...
- 让你彻底理解TypeScript中的readonly
1.readonly的讲解 readonly修饰符,首先是一个关键字 对类中的属性成员进行修饰修饰之后,该属性成员就不能修改了.只能够进行访问 在构造函数中是可以对只读属性(readonly)进行修改 ...
- Python 潮流周刊#22:Python 3.12.0 发布了!!
你好,我是猫哥.这里每周分享优质的 Python.AI 及通用技术内容,大部分为英文.标题取自其中一则分享,不代表全部内容都是该主题,特此声明. 本周刊由 Python猫 出品,精心筛选国内外的 25 ...
- 使用TimeSpan 日期与时间拼接
TimeSpan 含有以下四个构造函数: TimeSpan(Int64)将 TimeSpan结构的新实例初始化为指定的刻度数. (DateTime.Tick:是计算机的一个计时周期,单位是一百纳秒,即 ...
- Paddlenlp之UIE分类模型【以情感倾向分析新闻分类为例】含智能标注方案)
相关文章: Paddlenlp之UIE模型实战实体抽取任务[打车数据.快递单] 项目连接:百度AIstudio直接fork我的项目就可以复现 Paddlenlp之UIE分类模型[以情感倾向分析新闻分类 ...
- C# 语言程序设计笔记
C#是一种最新的.面向对象的编程语言.它使得程序员可以快速地编写各种基于Microsoft .NET平台的应用程序,Microsoft .NET提供了一系列的工具和服务来最大程度地开发利用计算与通讯领 ...
- 香橙派上的eMMC分区
准备工作 OrangePi Plus 2E(自带16G的eMMC存储,出厂默认eMMC中附带了Android系统,用于测试板子功能) Ubuntu16.04的TF卡 第一张方式: 该方式可以按需删除指 ...