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

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

本文主要是介绍中文字符编码之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

相关文章

基于Go语言实现Base62编码的三种方式以及对比分析

《基于Go语言实现Base62编码的三种方式以及对比分析》Base62编码是一种在字符编码中使用62个字符的编码方式,在计算机科学中,,Go语言是一种静态类型、编译型语言,它由Google开发并开源,... 目录一、标准库现状与解决方案1. 标准库对比表2. 解决方案完整实现代码(含边界处理)二、关键实现细

idea报错java: 非法字符: ‘\ufeff‘的解决步骤以及说明

《idea报错java:非法字符:‘ufeff‘的解决步骤以及说明》:本文主要介绍idea报错java:非法字符:ufeff的解决步骤以及说明,文章详细解释了为什么在Java中会出现uf... 目录BOM是什么?1. BOM的作用2. 为什么会出现 \ufeff 错误?3. 如何解决 \ufeff 问题?最

使用Java编写一个字符脱敏工具类

《使用Java编写一个字符脱敏工具类》这篇文章主要为大家详细介绍了如何使用Java编写一个字符脱敏工具类,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1、字符脱敏工具类2、测试工具类3、测试结果1、字符脱敏工具类import lombok.extern.slf4j.Slf4j

解决IDEA报错:编码GBK的不可映射字符问题

《解决IDEA报错:编码GBK的不可映射字符问题》:本文主要介绍解决IDEA报错:编码GBK的不可映射字符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录IDEA报错:编码GBK的不可映射字符终端软件问题描述原因分析解决方案方法1:将命令改为方法2:右下jav

Python使用自带的base64库进行base64编码和解码

《Python使用自带的base64库进行base64编码和解码》在Python中,处理数据的编码和解码是数据传输和存储中非常普遍的需求,其中,Base64是一种常用的编码方案,本文我将详细介绍如何使... 目录引言使用python的base64库进行编码和解码编码函数解码函数Base64编码的应用场景注意

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

VSCode中C/C++编码乱码问题的两种解决方法

《VSCode中C/C++编码乱码问题的两种解决方法》在中国地区,Windows系统中的cmd和PowerShell默认编码是GBK,但VSCode默认使用UTF-8编码,这种编码不一致会导致在VSC... 目录问题方法一:通过 Code Runner 插件调整编码配置步骤方法二:在 PowerShell

一文教你解决Python不支持中文路径的问题

《一文教你解决Python不支持中文路径的问题》Python是一种广泛使用的高级编程语言,然而在处理包含中文字符的文件路径时,Python有时会表现出一些不友好的行为,下面小编就来为大家介绍一下具体的... 目录问题背景解决方案1. 设置正确的文件编码2. 使用pathlib模块3. 转换路径为Unicod

Python如何实现读取csv文件时忽略文件的编码格式

《Python如何实现读取csv文件时忽略文件的编码格式》我们再日常读取csv文件的时候经常会发现csv文件的格式有多种,所以这篇文章为大家介绍了Python如何实现读取csv文件时忽略文件的编码格式... 目录1、背景介绍2、库的安装3、核心代码4、完整代码1、背景介绍我们再日常读取csv文件的时候经常

C# string转unicode字符的实现

《C#string转unicode字符的实现》本文主要介绍了C#string转unicode字符的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录1. 获取字符串中每个字符的 Unicode 值示例代码:输出:2. 将 Unicode 值格式化