ASCII Unicode, UTF8 的关系,string和wstring转换

2023-11-14

  写这篇文章遇到的的问题是c++操作正则的时候,遇到中文出现匹配失败。以及visual studio中中文乱码问题。当时这里卡住了项目进程,最后花费很多时间才解决。主要问题是中文编码编码问题。特记录分享,避免踩坑。

1. 三大编码由来和转换

  计算机中所有数据存储都是01两个量表示,但是如何将01转换为我们日常使用的字符,这就依赖编码。众所周知,最早的计算机是美国人发明的,所以计算机最早表达的语言肯定是英文。英文字母只有26个。所以提出了单字节编码ASCII编码。用来解决字符在计算机中的存储表示问题。如大写的字符A编码为65(二进制01000001)一个字节就可以存储。

 ASCII : 使用指定的 7 位或 8 位二进制数(单字节)组合来表示 128 或 256 种可能的字符。标准 ASCII 码也叫基础ASCII码,使用 7 位二进制数来表示所有的大写和小写字母,数字 0 到 9、标点符号, 以及在美式英语中使用的特殊控制字符。

  其他国家,比如汉语也有字符编码的需求。但是ASCII采用单字节,表示的字符有限,无法满足其他语言编码的拓展。于是推出了多字节编码的Unicode编码来满足大多数国家的文字的编码。如:字符‘A’的编码为00000000 01000001,就是在ASCII中在高位加8个0。

Unicode:采用的是两个字节(16位二进制)来表示字符,这样能基本满足各种国家语言字符的需求。

  虽然Unicode编码解决了世界文字编码大一统的问题,但Unicode只规定了符号的二进制编码,而并没有规定这个而二进制编码如何存储。通常一个中文字符需要两个字节来存储,特殊的字符可能需要三个四个字节存储。计算机无法知道几个字节表示一个字符,也就无法识别unicode码。如果规定每个unicode码用固定的多个字节来保存,那英文字符前面需要添加多个0,这是对存储是极大的浪费。在解决内存空间这件事上,从来难不倒抠门的码农。于是设计出了UTF8编码。

UTF-8: 是一种针对Unicode的可变长度的字符编码方式。它可以用一至四个字节对Unicode字符集中的所有有效编码点进行编码。

  UTF8编码是一种变长的编码方式。其使用1-4字节来表示一个符号 。UTF8编码方式很简单,只有两个规则:

 >1.  对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。 
以A为例:
ASCII: 01000001 --> Unicode: 00000000 01000001 --> UTF8: 01000001
  1. 对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。
以‘中’(4E2D)字为例:4E2D 在在第三行的范围内(0000 0800 - 0000 FFFF)所以‘中’编码需要三个字节。即格式是1110 xxxx 10xx xxxx 10xx xxxx。从最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。
UTF8: 100 1110 0010 1101    -> Unicode: 1110 0100 1011 1000 1010 1101

2. 三大编码在计算机中应用:

  1. 在计算机内存磁盘交互场景中:

  在计算机内存中统一使用Unicode编码,进行字符处理,但是数据保存到磁盘文件中,先转换成UTF8以节约空间,然后呢存储。

  内存读取磁盘文件中字符数据,也需要先将UTF8数据转换成Unicode编码,然后保存在内存中供计算机处理。

请添加图片描述

  1. web数据传输:

  服务器中以Unicode编码,来保存数据,但是在向浏览器发送数据时候,会将字符转换成UTF8,发送给浏览器。以缩小通信数据。

请添加图片描述

3. char(string)和wchar_t (wstring)转换

  关于这个问题的讨论起源于正则表达式。在中文匹配的时候,正则表达式无法匹配到中文符号。经过查阅资料发现,正则表达表达式是按照Unicode编码来匹配中文的。但是string中存储的是中文是UTF8编码,而非Unicode编码的字符导致无法匹配。要想正则表达是必须将中文字符集编码转换成Unicode编码。

window:转换

        std::wstring Utf82Unicode(const std::string& utf8){
            int unicodeLen = MultiByteTowideChar(CP_UTF8, 0, utf8.c_str(), -1, nullptr,0);
            wchar_t* pUnicode = (wchar_t*)malloc(sizeof(wchar_t) * unicodeLen);
            MultiByteTowideChar(CP_UTF8, 0, utf8.c_str()-1, pUnicode, unicodeLen);
            std::wstring ret str = pUnicode;
            free(pUnicode);
            return ret str;
        }
        
        std::string Unicode2Utf8(const std::wstring& wstr)
        int ansiilen = WideCharToMultiByte(CP_UTF8, 0, wstr.c str(), -1, nullptr, 0, nullptr, nullptr);
        char* pAscii = (char*)malloc(sizeof(char) * ansiiLen);
        WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, pAssii, ansiilen, nullptr, nullptr);
        std::string str = pAscii;
        free(pAscii);
        return str;
        
        std::wstring Ascii2Unicode(const std::string& str){
            int unicodeLen = MultiByteTowideChar(CP ACP, , str.c_str(), -1, nullptr,0);
            wchar_t* pUnicode = (wchar_t*)malloc(sizeof(wchar_t) *unicodeLen);
            MultiByteTowideChar(CP_ACP, 0, str.c_str()-1, pUnicode, unicodeLen);
            std::wstring str = pUnicode;
            free(pUnicode):
            return str;
        }
        
        
        std::string Unicode2Ascii(const std::wstring& wstr){
            int ansiilen = WidecharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, nullptr, 0, nullptr, nullptr);
            char* pAssii = (char*)malloc(sizeof(char) * ansiiLen);
            WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), -1, pAssii, ansiilen, nullptr, nullptr);
            std::string str = pAssii;
        	free(pAssii);
        	return str;
        }
        
        
         // utf8和ascii 无法直接互转可通过unicode 转换实现。
        

linux:转换

        std::wstring Utf82Unicode(const std::string& utf8){
        	wstring result;
            const char * pUtf8Buff = utf8.c_str();
            // 地域设置信息
        	char* old locale = setlocale(LC_CTYPE,"en_US.UTF8");
            //将多字节字符串转换为宽字符串,确定宽字节长度
            int unicode buff size = mbstowcs(NULL, pUtf8Buff, 0);
            if(0 == unicode buff_size){
        		return result;
            }
        	unicode_buff_size += 8; // 给更多额外的空间
        	result.resize(unicode_buff_size):
            //将多字节字符串转换为宽字串
            unicode_buff_size = mbstowcs((wchar t*)result.c_str(), putf8Buff, unicode_buff_size + 1):
            setlocale(LC_CTYPE, old_locale);
            return result:
        }
        
        
        std::string Unicode2Utf8(const std::wstring& wstr) {
            string result;
        	const wchar t * pwBuff = wstr.c_str();//地域设置信息
        	char* old locale = setlocale(LC_CTYPE,"en_US.UTF8");
            int Utf8Buffsize = wcstombs(NULL, pwBuf, 0);
            if( == Utf8Buffsize) {
                return result;
            }
        	Utf8Buffsize += 8; // 给更多额外的空间result.resize(Utf8Buffsize);
        	Utf8Buffsize = wcstombs((char*)result.c_str(), pwBuff Utf8Buffsize + 1);
            setlocale(LC_CTYPE, old_locale);
            return result:
        }
        
        
        
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ASCII Unicode, UTF8 的关系,string和wstring转换 的相关文章

  • 当我使用“control-c”关闭发送对等方的套接字时,为什么接收对等方的套接字不断接收“”

    我是套接字编程的新手 我知道使用 control c 关闭套接字是一个坏习惯 但是为什么在我使用 control c 关闭发送进程后 接收方上的套接字不断接收 在 control c 退出进程后 发送方的套接字不应该关闭吗 谢谢 我知道使用
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • 未解决的包含:“cocos2d.h” - Cocos2dx

    当我在 Eclipse 中导入 cocos2dx android 项目时 我的头文件上收到此警告 Unresolved inclusion cocos2d h 为什么是这样 它实际上困扰着我 该项目可以正确编译并运行 但我希望这种情况消失
  • C++ 子字符串返回错误结果

    我有这个字符串 std string date 20121020 我正在做 std cout lt lt Date lt lt date lt lt n std cout lt lt Year lt lt date substr 0 4 l
  • 实时服务器上的 woff 字体 MIME 类型错误

    我有一个 asp net MVC 4 网站 我在其中使用 woff 字体 在 VS IIS 上运行时一切正常 然而 当我将 pate 上传到 1and1 托管 实时服务器 时 我得到以下信息 网络错误 404 未找到 http www co
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • C - 找到极限之间的所有友好数字

    首先是定义 一对友好的数字由两个不同的整数组成 其中 第一个整数的除数之和等于第二个整数 并且 第二个整数的除数之和等于第一个整数 完美数是等于其自身约数之和的数 我想做的是制作一个程序 询问用户一个下限和一个上限 然后向他 她提供这两个限
  • 将目录压缩为单个文件的方法有哪些

    不知道怎么问 所以我会解释一下情况 我需要存储一些压缩文件 最初的想法是创建一个文件夹并存储所需数量的压缩文件 并创建一个文件来保存有关每个压缩文件的数据 但是 我不被允许创建许多文件 只能有一个 我决定创建一个压缩文件 其中包含有关进一步
  • 从路径中获取文件夹名称

    我有一些路c server folderName1 another name something another folder 我如何从那里提取最后一个文件夹名称 我尝试了几件事 但没有成功 我只是不想寻找最后的 然后就去休息了 Thank
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • 当操作繁忙时,表单不执行任何操作(冻结)

    我有一个使用 C 的 WinForms 应用程序 我尝试从文件中读取一些数据并将其插入数据表中 当此操作很忙时 我的表单冻结并且无法移动它 有谁知道我该如何解决这个问题 这可能是因为您在 UI 线程上执行了操作 将文件和数据库操作移至另一个
  • 如何使我的表单标题栏遵循 Windows 深色主题?

    我已经下载了Windows 10更新包括黑暗主题 文件资源管理器等都是深色主题 但是当我创建自己的 C 表单应用程序时 标题栏是亮白色的 如何使我自己的桌面应用程序遵循我在 Windows 中设置的深色主题 你需要调用DwmSetWindo
  • 将文本叠加在图像背景上并转换为 PDF

    使用 NET 我想以编程方式创建一个 PDF 它仅包含一个背景图像 其上有两个具有不同字体和位置的标签 我已阅读过有关现有 PDF 库的信息 但不知道 如果适用 哪一个对于如此简单的任务来说最简单 有人愿意指导我吗 P D 我不想使用生成的
  • 在 Dynamics CRM 插件中访问电子邮件发件人地址

    我正在编写一个 Dynamics CRM 2011 插件 该插件挂钩到电子邮件实体的更新后事件 阶段 40 pipeline http msdn microsoft com en us library gg327941 aspx 并且在此阶
  • WCF:将随机数添加到 UsernameToken

    我正在尝试连接到用 Java 编写的 Web 服务 但有些东西我无法弄清楚 使用 WCF 和 customBinding 几乎一切似乎都很好 除了 SOAP 消息的一部分 因为它缺少 Nonce 和 Created 部分节点 显然我错过了一
  • 为什么 C# Math.Ceiling 向下舍入?

    我今天过得很艰难 但有些事情不太对劲 在我的 C 代码中 我有这样的内容 Math Ceiling decimal this TotalRecordCount this PageSize Where int TotalRecordCount
  • 为什么我收到“找不到编译动态表达式所需的一种或多种类型。”?

    我有一个已更新的项目 NET 3 5 MVC v2 到 NET 4 0 MVC v3 当我尝试使用或设置时编译出现错误 ViewBag Title财产 找不到编译动态表达式所需的一种或多种类型 您是否缺少对 Microsoft CSharp
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a
  • 使用按位运算符相乘

    我想知道如何使用按位运算符将一系列二进制位相乘 但是 我有兴趣这样做来查找二进制值的十进制小数值 这是我正在尝试做的一个例子 假设 1010010 我想使用每个单独的位 以便将其计算为 1 2 1 0 2 2 1 2 3 0 2 4 虽然我

随机推荐

  • maven依赖范围之import

    maven依赖范围之import import依赖范围 该依赖范围不会test compile runtime的 classpath 产生实际的影响 它的作用是将其他模块定义好的 dependencyManagement 导入当前 Mave
  • 解决问题win10“.dll(或者,ocx)控件已加载,但对DllregisterServer的调用失败,错误代码为0x80070005”

    重构机房的过程需要参考用VB生成的 机房收费系统 安装后需要执行的步骤 第一 需要配置文件DSN 文件名称 charge 服务器 local 用户名 sa 密码 123456 数据库 charge sys 第二 附加数据库 第三 需要注册文
  • PCL Harris3D关键点提取

    目录 一 算法原理 1 原理概述 2 实现流程 2 1 2d Harris 算法 2 2 3d Harris 算法 3 注意事项 4 参考文献 二 代码实现 三 结果展示 四 参数解析 一 算法原理 1 原理概述
  • 关于PCB走线,铜厚与允许的最大电流之间的关系

    最近在看西安电子科技大学庄奕琪教授的 电子设计可靠性工程 这本书对于电子专业的工程师 学生来说 真的特别实用 其中他并没有提到关于EMC EMI之类的词语 但是关于电磁兼容 电磁屏蔽之类的一些操作都写的非常详细 做笔记做笔记 关于PCB走线
  • 孟德尔随机化推断暴露因素与健康结局的因果关系

    学习视频 应用孟德尔随机化方法推断暴露因素与健康结局的因果关系 王友信教授 梅斯医学 哔哩哔哩 bilibili http chinaepi icdc cn zhlxbx ch reader create pdf aspx file no
  • 应用计算机测定线性电阻电路图和实物图,PC817中文数据摘要_PC817引脚图和功能_工作原理_特性参数及典型应用电路...

    首先 PC817中文数据摘要 PC817简介 PC817光耦合器广泛用于计算机终端 晶闸管系统设备 测量仪器 复印机 自动售票 家用电器 如风扇 加热器 和其他在前端和负载之间进行信号传输的电路 目的是提高安全性 减少电路干扰并简化电路设计
  • Cookie实现简化登录

    写在前面 以下只用于自己复习 仅供参考 有不到位或错误的地方欢迎指出 非常感谢 目录 一 Cookie介绍 1 Cookie概念 2 Cookie作用 3 Cookie的使用原则 二 相关操作 1 客户端页面 2 后台数据处理 一 Cook
  • java中==与equals的区别

    String a hello String b hello String c new String hello System out println a b System out println a equals b System out
  • SD卡引脚 电路图及工作原理介绍

    对于SD卡的硬件结构 在官方的文档上有很详细的介绍 如SD卡内的存储器结构 存储单元组织方式等内容 要实现对它的读写 最核心的是它的时序 笔者在经过了实际的测试后 使用51单片机成功实现了对SD卡的扇区读写 并对其读写速度进行了评估 下面先
  • android log处理

    今天是新年上班的第一天 好高兴啊 感觉公司好亲切 可不是 开门红包抽中最高的啦 今天计划实现把导致软件崩溃的bug发送到服务器端 好让我根据bug 调试程序 通过查阅资料 遇到以下几个问题 1 把log文件发送到服务器 这个log是使程序崩
  • LINUX学习--页面认识和常用命令

    目录 前言 一 LINUX界面 1 Linux图形界面 2 Linux文本界面 3 界面切换 4 终端 判断自己是否有网 二 LINUX目录介绍 1 设计思想 2 常用目录 三 LINUX基本命令 1 LINUX命令格式 2 LINUX命令
  • AI绘图MidJourney提示词详解——美女画法(1)

    AI绘图MidJourney提示词详解 美女画法 1 前言 提示词基本公式 1 1 公式参数说明 编写提示词 Prompt 2 1 题目 2 2 提示词描述 2 3 生成提示词 获取更多信息 前言 Midjourney Prompt即提示词
  • 浙江大学【面板数据分析与STATA应用】——第一讲短面板数据分析

    基本概念 面板数据及分类 面板数据分类 短面板和长面板 动态面板和静态面板 平衡面板和非平衡面板 截面数大于时间数就是短面板 反之 则为长面板 解释变量包含被解释变量的滞后值则为动态面板 反之 则为静态面板 平衡面板 每个个体在想他的时间内
  • zabbix api无法获取已解决问题解决思路和总结

    zabbix api无法获取已解决问题解决思路和总结 事件背景 最近在对zabbix api进行二次开发 在设计获取problem的接口的时候发现了调用zabbix api无法获取已解决的problem的问题 在解决这个问题的过程之中对于z
  • aigc是什么,aigc和chatGPT的区别,aigc商业应用场景

    AIGC是Artificial Intelligence Graphics Computing的缩写 意为人工智能图形计算 它是一个涵盖了人工智能 计算机图形学和深度学习等领域技术的综合平台 其目的是将这些技术结合起来 实现更加高效 智能化
  • 深度学习发展历程全讲解

    深度学习发展历程 深度学习综述 1 基本概念 2人工智能发展和内容 2 1 AI目标 2 2 AI领域 3 机器学习发展内容 3 1 发展阶段 3 2 任务 3 3目标 3 4算法 3 5 学习方式 4深度学习发展内容 4 1 深度学习的发
  • TortoiseSvn不显示图标问题解决方法

    TortoiseSvn不显示图标问题解决方法 问题原因 windows系统中最多显示指定数量的图标 超过一定数量后 之后的图标不会显示 解决方式 右击自己的svn项目 TortoiseSvn gt Settings 按照上图的箭头操作 会打
  • easyExcel日期字符串格式统一处理

    1 遇到日期导入转换Date失败情况 excel里面日期是字符串 java实体类和数据库都是日期类型 导入转换 public class EasyExcelString2DateConvert implements Converter
  • 深度学习之图像分类学习笔记(一)图像卷积与滤波

    转载自 http blog csdn net zouxy09 article details 49080029 写的很清楚 解决了我对于卷积理解的困难 一 线性滤波与卷积的基本概念 线性滤波可以说是图像处理最基本的方法 它可以允许我们对图像
  • ASCII Unicode, UTF8 的关系,string和wstring转换

    目录 1 三大编码由来和转换 2 三大编码在计算机中应用 3 char string 和wchar t wstring 转换 写这篇文章遇到的的问题是c 操作正则的时候 遇到中文出现匹配失败 以及visual studio中中文乱码问题 当