中文字符编码之GBK,UTF-16和UTF-8

2024-06-23 09:18
文章标签 utf gbk 16 编码 字符 中文

本文主要是介绍中文字符编码之GBK,UTF-16和UTF-8,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

编程中经常会遇到这三种字符编码形式的相互转换问题,以至于许多第三方的库不明原因的调用失败,其实很多都是由于第三方库支持的是utf-8而不是windows默认支持的utf-16导致的。

下面介绍一下windows系统下常见的这三种字符编码方式。

GB2312

是我们国家自己国标的汉字编码字符集,该字符集以一个16位的2进制数据单元表示一个汉字,所以能够将两个char型数据单元保存一个汉字。

微软的Windows操作系统汉字的编码字符集支持GB2312。这就是为什么我们用:

constchar* pChar = “中文”;

printf(pChar);

能够正确显示中文的原因。

但是,假如我们现在要将程序转换为一种除了中文和标准ASCII字符之外的文字时(比如说韩文),由于韩文不能被GB2312解析,所以就会产生乱码。

这就是为什么微软推荐采用Unicode的原因。因为Unicode包含了所有人类已知的文字字符集,理论上可以解析所有文字。

 

Unicode

Unicode字符集实际上是国际标准 ISO 10646 的一个子集。Unicode字符集是由Unicode协会公布的

 

ISO 10646定义了 通用字符集 (Universal Character Set, UCS). UCS 是所有其他字符集标准的一个超集。ISO10646 定义了一个 31 位的字符集. 然而, 在这巨大的编码空间中, 迄今为止只分配了前 65534 个码位(0x0000 0xFFFD). 这个 UCS 16位子集称为基本多语言面 (Basic Multilingual Plane, BMP). 将被编码在 16 BMP 以外的字符都属于非常特殊的字符(比如象形文字), 且只有专家在历史和科学领域里才会用到它们.

 

 UTF-16

UCS Unicode 只是分配整数给字符的编码表.现在存在好几种将一串字符表示为一串字节的方法. 最显而易见的两种方法是将Unicode 文本存储为 2 4 个字节序列的串. 这两种方法的正式名称分别为 UCS-2 UCS-4. WindowsUnicode表示方式极为UCS-2,即用两个字节表示一个Unicode字符。

除非另外指定, 否则大多数的字节都是Bigendian convention. 将一个 ASCII Latin-1 的文件转换成 UCS-2 只需简单地在每个ASCII 字节前插入 0x00. 如果要转换成UCS-4, 则必须在每个 ASCII 字节前插入三个0x00.

Windows内部使用UCS-2标准,并用UTF-16实现。在基本多语言平面内定义的符号((Basic MultilingualPlane, BMP),或称第零平面(Plane 0)),使用2个字节表示。

所以,Windows中使用的wchar_t的单位为2个字节,一个ASCII字符也要用两个字节表示。

Java采用的也是UTF-16

 

UTF-8

Unix 下使用 UCS-2 (UCS-4) 会导致非常严重的问题. 用这些编码的字符串会包含一些特殊的字符, 比如'\0' '/', 它们在文件名和其他 C 库函数参数里都有特别的含义.另外,大多数使用ASCII 文件的 UNIX 下的工具, 如果不进行重大修改是无法读取 16 位的字符的. 基于这些原因, 在文件名, 文本文件, 环境变量等地方,UCS-2 不适合作为Unicode 的外部编码.

ISO10646-1 Annex R RFC 2279 里定义的UTF-8 编码没有这些问题. 它是在Unix 风格的操作系统下使用 Unicode 的明显的方法.

 

UTF-8有一下特性:

  • UCS 字符 U+0000 到 U+007F (ASCII) 被编码为字节 0x00 到 0x7F (ASCII 兼容). 这意味着只包含 7 位 ASCII 字符的文件在 ASCII 和 UTF-8 两种编码方式下是一样的.
  • 所有 >U+007F 的 UCS 字符被编码为一个多个字节的串, 每个字节都有标记位集. 因此, ASCII 字节 (0x00-0x7F) 不可能作为任何其他字符的一部分.
  • 表示非 ASCII 字符的多字节串的第一个字节总是在 0xC0 到 0xFD 的范围里, 并指出这个字符包含多少个字节. 多字节串的其余字节都在 0x80 到 0xBF 范围里. 这使得重新同步非常容易, 并使编码无国界, 且很少受丢失字节的影响.
  • 可以编入所有可能的 231个 UCS 代码
  • UTF-8 编码字符理论上可以最多到 6 个字节长, 然而 16 位 BMP 字符最多只用到 3 字节长.
  • Bigendian UCS-4 字节串的排列顺序是预定的.
  • 字节 0xFE 和 0xFF 在 UTF-8 编码中从未用到.

注意在多字节串中, 第一个字节的开头"1"的数目就是整个串中字节的数目.

UTF-8web协议和Unix族的操作系统中广泛使用。ASCII不作变换, 其他字符做变长编码, 每个字符1-3byte.

 搞清了这三种编码方式,下面再谈一下如何相互转化的问题。

//wchar_t转成UTF-8     
inline string ConvertWChar2UTF8( const wchar_t* a_szSrc )     
{         const int nszBuffer = WideCharToMultiByte( CP_UTF8, 0, a_szSrc, -1, NULL, 0, NULL, NULL );     char* Buffer = new char[nszBuffer];  WideCharToMultiByte( CP_UTF8, 0, a_szSrc, -1, Buffer, nszBuffer, NULL, NULL );     string strReturn = Buffer;  delete[] Buffer;  return strReturn;  
} ;


这篇关于中文字符编码之GBK,UTF-16和UTF-8的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1086743

相关文章

2024.6.24 IDEA中文乱码问题(服务器 控制台 TOMcat)实测已解决

1.问题产生原因: 1.文件编码不一致:如果文件的编码方式与IDEA设置的编码方式不一致,就会产生乱码。确保文件和IDEA使用相同的编码,通常是UTF-8。2.IDEA设置问题:检查IDEA的全局编码设置和项目编码设置是否正确。3.终端或控制台编码问题:如果你在终端或控制台看到乱码,可能是终端的编码设置问题。确保终端使用的是支持你的文件的编码方式。 2.解决方案: 1.File -> S

16.Spring前世今生与Spring编程思想

1.1.课程目标 1、通过对本章内容的学习,可以掌握Spring的基本架构及各子模块之间的依赖关系。 2、 了解Spring的发展历史,启发思维。 3、 对 Spring形成一个整体的认识,为之后的深入学习做铺垫。 4、 通过对本章内容的学习,可以了解Spring版本升级的规律,从而应用到自己的系统升级版本命名。 5、Spring编程思想总结。 1.2.内容定位 Spring使用经验

剑指offer(C++)--第一个只出现一次的字符

题目 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写). class Solution {public:int FirstNotRepeatingChar(string str) {map<char, int> mp;for(int i = 0; i < str.size(); ++i)m

完整的申请邓白氏编码的流程(手把手教你申请邓白氏编码

完整的申请邓白氏编码的流程(手把手教你申请邓白氏编码)  标签: 编码邓白氏编码申请流程苹果开发者账号申请 2016-07-08 16:13  2274人阅读  评论(2)  收藏  举报   分类: 技术  苹果开发  邓白氏编码申请 版权声明:本文为博主原创文章,未经博主允许不得转载。     申请公司的苹果开发者账号和企业级的苹

【Qt6.3 基础教程 16】 掌握Qt中的时间和日期:QTimer和QDateTime的高效应用

文章目录 前言QTimer:定时任务的强大工具QTimer的基本用法高级特性:单次定时器 QDateTime:处理日期和时间获取当前日期和时间日期和时间的格式化输出日期和时间计算 用例:创建一个倒计时应用结论 前言 在开发桌面应用程序时,处理时间和日期是一个常见且重要的任务。Qt框架提供了强大的工具来处理与时间相关的功能,其中QTimer和QDateTime是最核心的类。本

linux匹配Nginx日志,某个字符开头和结尾的字符串

匹配 os=1 开头, &ip结尾的字符串 cat 2018-06-07.log | egrep -o ‘os=1.*.&ip’ 存入日志。然后使用submit 前面和后面的值去掉,剩下就是需要的字符串。 cat 2018-06-07.log | egrep -o ‘os=1.*.&ip’ >log.log

C语言中的字符输入/输出和验证输入

在C语言中,字符输入/输出功能允许程序与用户进行交互,读取用户的输入信息并展示输出结果。同时,验证输入的作用在于确保用户输入的数据符合预期,以提高程序的稳定性和可靠性,防止无效输入引发的错误或异常行为,从而提供更好的用户体验。 基础概念 输入(Input):指的是向程序填充数据的过程,通常来源于用户输入、文件读取或其他外部数据源。 输出(Output):指的是将数据显示在屏幕上、打印机上或

Linux float int和16进制互相转换

Linux 上float int和16进制互换操作。之前把float转16进制,也就是转成4个字节,方便使用串口传输嘛。使用的方法是: //float 转 16进制float x_pid_p = 15.0;unsigned char * bValue = (unsigned char *)& x_pid_p;printf("%x\t%x\t%x\t%x\n", bValue[0], bVa

android 中文api (84) —— TrafficStats

android 中文api (84) —— TrafficStats   前言   本章内容是android.net.TrafficStats,译为"流量统计",版本为Android 2.3 r1 ,翻译参考“Android开发网”的这篇文章,欢迎访问他们的网址:“http://android123.com.cn/”。期待你一起参与Android API 的中文翻译,联系我over140@g

2021-02-16物料档案条码添加和蓝牙条码标签打印,金蝶安卓盘点机PDA,金蝶仓库条码管理WMS系统

物料档案条码添加和蓝牙条码标签打印,金蝶安卓盘点机PDA https://member.bilibili.com/platform/upload-manager/article 本期视频我们来讲解一下汉点机PDA条码添加和条码标签蓝牙便携打印: 在实际使用中,我们商品有两种情况: 一种是商品本身就有条码, 比如:超市卖的可口可乐,牛奶等商品,商品本身就有69开头的国标码,那么我们就可以使用盘点