C++ UTF-8编解码

news2024/12/28 18:38:12


icu 编解码数据:
extern const UConverterSharedData
    _MBCSData, _Latin1Data,
    _UTF8Data, _UTF16BEData, _UTF16LEData, _UTF32BEData, _UTF32LEData,
    _ISO2022Data, 
    _LMBCSData1,_LMBCSData2, _LMBCSData3, _LMBCSData4, _LMBCSData5, _LMBCSData6,
    _LMBCSData8,_LMBCSData11,_LMBCSData16,_LMBCSData17,_LMBCSData18,_LMBCSData19,
    _HZData,_ISCIIData, _SCSUData, _ASCIIData,
    _UTF7Data, _Bocu1Data, _UTF16Data, _UTF32Data, _CESU8Data, _IMAPData, _CompoundTextData;

U_CDECL_END

Code point 代码点    Byte 1         Byte 2         Byte 3         Byte 4
U+ 0000 .. 007F        0xxxxxxx
U+ 0080 .. 07FF        110xxxxx    10xxxxxx
U+ 0800 .. FFFF        1110xxxx    10xxxxxx    10xxxxxx
U+ 10000 .. 10FFFF    11110xxx    10xxxxxx    10xxxxxx    10xxxxxx

可变长度编码
🚵🏻‍♀️ is U+1F6B5 + U+1F3FB + U+200D + U+2640 + U+FE0F
🤦🏼‍♂️ 由 5 个代码点 ( U+1F926 U+1F3FB U+200D U+2642 U+FE0F ) 
组成的事实仅仅是实现细节。它不应该被拆开,它不应该被计为多个字符,文本光标不应该位于其中,它不应该被部分选择

关键代码

std::size_t sequence_length(char8_t lead_byte)
{
    if (lead_byte < 0x80)
        return 1;
    else if ((lead_byte >> 5) == 0x6)
        return 2;
    else if ((lead_byte >> 4) == 0xe)
        return 3;
    else if ((lead_byte >> 3) == 0x1e)
        return 4;
    else
        return 0;
}

UTF_ERROR encode_next_utf8(const char32_t code_point, std::u8string &utf8str)
{
    if (!is_code_point_valid(code_point))
        return UTF_ERROR::INVALID_CODE_POINT;

    if (code_point < 0x80) {  // 1 byte
        utf8str.append(1u, static_cast<char8_t>(code_point));
    } else if (code_point < 0x800) {  // 2 bytes
        add_capacity_if_needed(utf8str, 2);
        utf8str.append(1, static_cast<char8_t>((code_point >> 6) | 0xc0));
        utf8str.append(1, static_cast<char8_t>((code_point & 0x3f) | 0x80));
    } else if (code_point < 0x10000) {  // 3 bytes
        add_capacity_if_needed(utf8str, 3);
        utf8str.append(1, static_cast<char8_t>((code_point >> 12) | 0xe0));
        utf8str.append(1, static_cast<char8_t>(((code_point >> 6) & 0x3f) | 0x80));
        utf8str.append(1, static_cast<char8_t>((code_point & 0x3f) | 0x80));
    } else {  // 4 bytes
        add_capacity_if_needed(utf8str, 4);
        utf8str.append(1, static_cast<char8_t>((code_point >> 18) | 0xf0));
        utf8str.append(1, static_cast<char8_t>(((code_point >> 12) & 0x3f) | 0x80));
        utf8str.append(1, static_cast<char8_t>(((code_point >> 6) & 0x3f) | 0x80));
        utf8str.append(1, static_cast<char8_t>((code_point & 0x3f) | 0x80));
    }

    return UTF_ERROR::OK;
}

C++ 标准库

#include <locale>
#include <codecvt>
#include <fstream>
// convert std::string to wstring
std::wstring to_wide_string(const std::string &input)
{
    //    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    //    return converter.from_bytes(input);

    std::locale   sys_loc(std::locale("C.UTF-8"));
    std::ofstream ofs(" cvt_buf ");
    ofs << input;
    ofs.close();

    std::wifstream wifs(" cvt_buf ");
    wifs.imbue(sys_loc);
    std::wstring wstr;
    wifs >> wstr;
    wifs.close();

    return wstr;
}

// convert wstring to std::string
std::string to_byte_string(const std::wstring &input)
{
    // std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
    //    std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    //    return converter.to_bytes(input);
    std::locale    sys_loc(std::locale("C.UTF-8"));
    std::wofstream wofs(" cvt_buf ");
    wofs.imbue(sys_loc);
    wofs << input;
    wofs.close();

    std::ifstream ifs(" cvt_buf ");
    std::string   str;
    ifs >> str;
    ifs.close();

    return str;
}

std::u32string to_utf32(std::string str)
{
    return std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t>{}.from_bytes(str);
}

std::string to_utf8(std::u32string str32)
{
    return std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t>{}.to_bytes(str32);
}

参考

The Absolute Minimum Every Software Developer Must Know About Unicode in 2023 (Still No Excuses!) @ tonsky.me

GitHub - soasis/text: A spicy text library for C++ that has the explicit goal of enabling the entire ecosystem to share in proper forward progress towards a bright Unicode future.

utfcpp-3.2.1.tar.gz · src-openEuler/utf8cpp - Gitee.com

GitHub - nemtrif/utfcpp: UTF-8 with C++ in a Portable Way

GitHub - nemtrif/utfcpp20: Unicode encodings with C++20


创作不易,小小的支持一下吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1898437.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数字信号处理及MATLAB仿真(2)——离散系统

上回书说到如何来编写一些简单的离散时间序列&#xff0c;今天咱们就来谈谈一些关于常系数差分方程的操作吧。 说到这里咱们对于常系数差分方程可能最关心的就是怎么去求解了。 其中最关键的部分就是filter函数&#xff0c;可以用来计算系统在输入信号为x的输出信号y。大家学过…

Hilbert编码 思路和scala 代码

需求&#xff1a; 使用Hilbert 曲线对遥感影像瓦片数据进行编码&#xff0c;获取某个区域的编码值即可 Hilbert 曲线编码方式 思路 大致可以对四个方向的数据进行归类 左下左上右上右下 这个也对应着编码的顺序 思考在不同Hilbert深度&#xff08;阶&#xff09;情况下的…

【重磅】万能模型-直接能换迪丽热巴的模型

万能模型&#xff0c;顾名思义&#xff0c;不用重新训练src&#xff0c;直接可以用的模型&#xff0c;适应大部分原视频脸 模型用法和正常模型一样&#xff0c;但可以跳过训练阶段&#xff01;直接到合成阶段使用该模型 本模型没有做Xseg&#xff0c;对遮挡过多的画面不会自动适…

掌握 Postman 脚本:入门指南

在探索 API 测试自动化环墁下&#xff0c;Postman 脚本显现其强大功能和灵活性&#xff0c;它不仅仅是 API 测试的工具&#xff0c;更是一个综合性的自动化平台。 Postman 脚本简介 Postman 允许用户在 API 请求生命周期中运行 JavaScript 脚本&#xff0c;这些脚本分为以下三…

FineBI在线学习资源-数据处理

FineBI在线学习资源汇总&#xff1a; 学习资源 视频课程 帮助文档 问答 数据处理学习文档&#xff1a; 相关资料&#xff1a; 故事背景概述-https://help.fanruan.com/finebi6.0/doc-view-1789.html 基础表处理-https://help.fanruan.com/finebi6.0/doc-view-1791.html …

联合概率密度函数

目录 1. 什么是概率密度由联合概率密度求概率参考链接 1. 什么是概率密度 概率密度到底在表达什么&#xff1f; 外卖在20-40分钟内送达的概率 随机变量落在[20,40]之间的概率。下图中&#xff0c;对总面积做规范化处理&#xff0c;令总面积1&#xff0c; f ( x ) f(x) f(x)则成…

使用中国大陆镜像源安装最新版的 docker Deamon

在一个智算项目交付过程中&#xff0c;出现了新建集群中的全部 docker server V19 进程消失、仅剩 docker server 的 unix-socket 存活的现象。 为了验证是否是BD产品研发提供的产品deploy语句缺陷&#xff0c;需要在本地环境上部署一个简单的 docker Deamon 环境。尴尬的是&a…

SD16S1Y 符合GB2312标准16X16点阵汉字库芯片IC

一般概述 SD16S1Y是一款内含16x16点阵的汉字库芯片&#xff0c;支持GB2312国标简体汉字(含有国家信标委 合法授权)、ASCII字符。排列格式为竖置横排。用户通过字符内码&#xff0c;利用本手册提供的方法计算出 该字符点阵在芯片中的地址&#xff0c;可从该地址连续读出字…

【JavaWeb程序设计】JSP编程

目录 一、编写JSP页面&#xff0c;在界面上显示1-9&#xff0c;9个链接&#xff0c;单击每个链接&#xff0c;能够在另一个页面打印该数字的平方。 1. 运行截图 2. 第一个jsp页面&#xff08;index.jsp&#xff09; 3. 第二个jsp页面&#xff08;square.jsp&#xff09; 二…

信创-办公软件应用工程师认证

随着国家对信息技术自主创新的战略重视程度不断提升&#xff0c;信创产业迎来前所未有的发展机遇。未来几年内&#xff0c;信创产业将呈现市场规模扩大、技术创新加速、产业链完善和国产化替代加速的趋势。信创人才培养对于推动产业发展具有重要意义。应加强高校教育、建立人才…

卫星网络——Walker星座简单介绍

一、星座构型介绍 近年来&#xff0c;随着卫星应用领的不断拓展&#xff0c;许多任务已经无法单纯依靠单颗卫星来完成。与单个卫星相比&#xff0c;卫星星座的覆盖范围显著增加&#xff0c;合理的星座构型可以使其达到全球连续覆盖或全球多重连续覆盖&#xff0c;这样的特性使得…

SpringBoot的在线教育平台-计算机毕业设计源码68562

摘要 在数字化时代&#xff0c;随着信息技术的飞速发展&#xff0c;在线教育已成为教育领域的重要趋势。为了满足广大学习者对于灵活、高效学习方式的需求&#xff0c;基于Spring Boot的在线教育平台应运而生。Spring Boot以其快速开发、简便部署以及良好的可扩展性&#xff0c…

CVPR2024自动驾驶轨迹预测方向的论文整理

2024年自动驾驶轨迹预测方向的论文汇总 1、Producing and Leveraging Online Map Uncertainty in Trajectory Prediction 论文地址&#xff1a;https://arxiv.org/pdf/2403.16439 提出针对在线地图不确定性带给轨迹预测的影响对应的解决方案。 在轨迹预测中&#xff0c;利用在…

Linux系统的基础知识和常用命令

1、什么是Linux&#xff1f; 是一种免费使用和自由传播的类UNIX操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹于1991年10月5日首次发布&#xff0c;它主要受到Minix和Unix思想的启发&#xff0c;是一个基于POSIX的多用户、多任务、支持多线程和多CPU的操作系统。它能运行…

基于Springboot的智慧信息化机房管理系统

1 项目介绍 1.1 研究目的和意义 随着社会的快速发展&#xff0c;计算机的影响是全面且深入的。人们生活水平的不断提高&#xff0c;日常生活中人们对高校共享机房管理方面的要求也在不断提高&#xff0c;需要高校共享机房的人数更是不断增加&#xff0c;使得高校共享机房管理…

【Linux进阶】磁盘分区3——目录树,挂载

Linux安装模式下&#xff0c;磁盘分区的选择&#xff08;极重要&#xff09; 在Windows 系统重新安装之前&#xff0c;你可能会事先考虑&#xff0c;到底系统盘C盘要有多大容量&#xff1f;而数据盘D盘又要给多大容量等&#xff0c;然后实际安装的时候&#xff0c;你会发现其实…

【系统架构设计师】计算机组成与体系结构 ⑩ ( 磁盘管理 | 磁盘移臂调度算法 | 先来先服务算法 | 最短寻道时间优先 | 扫描算法 | 循环扫描算法 )

文章目录 一、磁盘移臂调度算法1、磁盘移臂调度算法简介2、先来先服务算法3、最短寻道时间优先4、扫描算法5、循环扫描算法 二、最短寻道时间优先算法示例 一、磁盘移臂调度算法 1、磁盘移臂调度算法简介 磁盘 数据块读取 的 性能 主要由 寻道时间旋转延时 决定 ; 旋转延时 …

软设之UML图中的用例图

UML图中用例图 用例图描述一组用例&#xff0c;参与者及它们之间的关系 关系包括&#xff1a; 包含关系&#xff0c;扩展关系&#xff0c;泛化关系 用例建模的流程&#xff1a; 识别参与者 合并需求获得用例 细化用例描述 调整用例模型

《C语言》认识数据类型和理解变量

&#x1f339;个人主页&#x1f339;&#xff1a;喜欢草莓熊的bear &#x1f339;专栏&#x1f339;&#xff1a;C语言基础 目录 前言 一、数据类型的介绍 1.1 字符型 1.2 整形 1.3 浮点型 1.4 布尔类型 1.5 各种数据类型的长度 1.5.1 sizeof操作符 1.5.2 数据类型长度…

【React Hooks原理 - useCallback、useMemo】

介绍 在实际项目中&#xff0c;useCallback、useMemo这两个Hooks想必会很常见&#xff0c;可能我们会处于性能考虑避免组件重复刷新而使用类似useCallback、useMemo来进行缓存。接下来我们会从源码和使用的角度来聊聊这两个hooks。【源码地址】 为什么要有这两个Hooks 在开始…