[字符编码]windwos下使用libiconv转换编码格式(二)
在http://t.csdnimg.cn/PLUuz笔记中实现了常用编码格式转换的功能,但这还是一个demo。因为代码中向libiconv库函数传递的字符串是存放在堆空间中的(我也是从网上找例子测试,是否一定要开辟堆空间存放还有待考证),如果一次性转换的字节数很巨大的话,就会导致内存空间不足,进而引发功能异常。
所以,对于需要大量转换的数据,应该采取分段多次转换的方法。
经过观察,有的编码格式每个字符对应的字节是固定的,这样分段是容易的。比如GB2312格式,一个字符占两个字节,那么每次处理的字节数就是2的整倍数即可。
除了上面说的字节数固定的情况,还有向utf8这种字符字节数会变化的情况,这种转换则需要复杂些的处理。
#include <iostream>#include <fstream> #include <string> #include <bitset> #include "iconv.h" //包函libiconv库头文件//导入libiconv库#pragma comment(lib,"libiconv.lib")bool readfile(const std::string& _filepath, std::string& _filecontent){bool res = false;std::ifstream file(_filepath);if (!file.is_open()) { // 检查文件是否成功打开 std::cerr << "无法打开文件" << _filepath << std::endl;}else {std::string line;while (std::getline(file, line)) { // 逐行读取文件内容 _filecontent += line;}res = true;}file.close(); // 关闭文件return res;}//使用 libiconv 进行int TransCore(const char* _pdesc, const char* _psrc, const char* _pstrin, size_t ilen, char* _pstrout, size_t* _polen){const char** ppin = &_pstrin;char** ppout = &_pstrout;iconv_t cd = iconv_open(_pdesc, _psrc);if (cd == (iconv_t)-1) {return -1;}memset(_pstrout, 0, *_polen);int res = iconv(cd, ppin, &ilen, ppout, _polen);std::cout <<__FUNCTION__<< " exec res = " << res << std::endl;iconv_close(cd);return res;}/*desc 目标编码字符串src 源编码字符串_strin 转换前内容_strout 转换后内容*/bool TransEncodeFormat(const char* _desc, const char* _src, const std::string& _strin, std::string& _strout) {bool res = false;if (_desc == nullptr || _src == nullptr || _strin.empty()) {std::cout << "入参不符合要求" << std::endl;return res;}size_t inlen = _strin.length();#ifdef LOGstd::cout << "需要转换的内容 : [" << _strin << "]" << std::endl;std::cout << "需要转换的字节数 : [" << inlen << "]" << std::endl;#endifsize_t outlen = inlen * 10;char* tempout = new char[outlen];if (TransCore(_desc, _src, _strin.c_str(), inlen, tempout, &outlen) == 0 && tempout != nullptr) {res = true;}#ifdef LOGstd::cout << "转换后的内容 : [" << tempout << "]" << std::endl;#endifstd::string temp(tempout);_strout = tempout;delete[] tempout;tempout = nullptr;return res;}/*描述 : 在_strin字符串是正确的utf8格式的情况下,分段将utf8字符转换成其他编码格式内容_desc : 目标编码格式_strin : 被转换的uft8字符串内容_strout: 转换后字符串内容_segnum: 一段字符串字节个数,默认是100字节返回值 : true 转换成功 false转换失败*/bool SegmentTransUtf8ToOther(const char* _desc, const std::string& _strin, std::string& _strout, const int& _segnum = 100) {const char* _src = "UTF-8";size_t _transcounter = 0;if (_strin.size() == 0) {//没有内容就返回_strout.clear();return true;}if (_segnum <= 0) {return false;}if (_strin.size() <= _segnum) {//字符串小于等于_segnumstd::cout << "第" << ++_transcounter << "段转换" <<",转换字节数"<< _strin.size() << std::endl;if (TransEncodeFormat(_desc, _src, _strin, _strout) == false) {return false;}}else {//字符串大于_segnumint leftpos = 0; //左边界位置int endpos = _strin.size() - 1; // 结束位置while (leftpos <= endpos) { int rightpos = 0;//右边界位置int remainingbytes = endpos - leftpos + 1; //左边界到结束剩余的字节数std::string outemp;if (remainingbytes <= _segnum) {//剩余字节数小于_segnumrightpos = endpos;std::string temp = _strin.substr(leftpos, remainingbytes); std::cout << "第" << ++_transcounter << "段转换" << ",转换字节数" << temp.size() << std::endl;if (TransEncodeFormat(_desc, _src, temp, outemp) == false) {return false;}_strout += outemp;} else {rightpos = leftpos + (_segnum - 1);const char lastbyte = _strin[rightpos];//通过要截取的最后一个字节 判断截取字符串是否完整if (((char)(lastbyte | 0x7f) == (char)0x7f) && ((char)(lastbyte & 0x00) == (char)0x00)) {//最后一个字节是 0XXX XXXXstd::string temp = _strin.substr(leftpos, rightpos - leftpos + 1);std::cout << "第" << ++_transcounter << "段转换" << ",转换字节数" << temp.size() << std::endl;if (TransEncodeFormat(_desc, _src, temp, outemp) == false) {return false;}_strout += outemp;} else if (((char)(lastbyte | 0xbf) == (char)0xbf) && ((char)(lastbyte & 0x80) == (char)0x80)) {//最后一个字节是 10XX XXXXwhile (1) {rightpos = rightpos + 1;if (rightpos > endpos) {//判断rightpos是否超出边界return false;}const char lastbytetemp = _strin[rightpos];if (((char)(lastbytetemp | 0xbf) == (char)0xbf) && ((char)(lastbytetemp & 0x80) == (char)0x80)) {//最后一个字节是 10XX XXXX}else {//最后一个字节不是 10XX XXXX 那么就少截取一个并跳出while循环rightpos = rightpos - 1;break;}}//whileif (rightpos < 0 || rightpos < leftpos) {//rightpos 上面进行了减法所以判断一下return false;}std::string temp = _strin.substr(leftpos, rightpos - leftpos + 1);std::cout << "第" << ++_transcounter << "段转换" << ",转换字节数" << temp.size() << std::endl;if (TransEncodeFormat(_desc, _src, temp, outemp) == false) {return false;}_strout += outemp;} else if (((char)(lastbyte | 0xdf) == (char)0xdf) && ((char)(lastbyte & 0xc0) == (char)0xc0)) {//最后一个字节是 110X XXXXrightpos = rightpos + 1;if (rightpos > endpos) {//判断rightpos是否超出边界return false;}std::string temp = _strin.substr(leftpos, rightpos - leftpos + 1);std::cout << "第" << ++_transcounter << "段转换" << ",转换字节数" << temp.size() << std::endl;if (TransEncodeFormat(_desc, _src, temp, outemp) == false) {return false;}_strout += outemp;} else if (((char)(lastbyte | 0xef) == (char)0xef) && ((char)(lastbyte & 0xe0) == (char)0xe0)) {//最后一个字节是 1110 XXXXrightpos = rightpos + 2;if (rightpos > endpos) {//判断rightpos是否超出边界return false;}std::string temp = _strin.substr(leftpos, rightpos - leftpos + 1);std::cout << "第" << ++_transcounter << "段转换" << ",转换字节数" << temp.size() << std::endl;if (TransEncodeFormat(_desc, _src, temp, outemp) == false) {return false;}_strout += outemp;} else if (((char)(lastbyte | 0xf7) == (char)0xf7) && ((char)(lastbyte & 0xf0) == (char)0xf0)) {//最后一个字节是 1111 0XXXrightpos = rightpos + 3;if (rightpos > endpos) {//判断rightpos是否超出边界return false;}std::string temp = _strin.substr(leftpos, rightpos - leftpos + 1);std::cout << "第" << ++_transcounter << "段转换" << ",转换字节数" << temp.size() << std::endl;if (TransEncodeFormat(_desc, _src, temp, outemp) == false) {return false;}_strout += outemp;}}leftpos = rightpos + 1;}}std::cout << __FUNCTION__ << " exec success" << std::endl;return true;}int main(int argc, char* argv[]){{std::string filecontent;std::string transcontent;std::string gbkfilepath = "./test-file/utf-8.txt";readfile(gbkfilepath, filecontent);std::cout << " ./test-file/utf-8.txt 内容字节数 = " << filecontent.size() << std::endl;bool res = SegmentTransUtf8ToOther("GBK", filecontent, transcontent, 1000);std::cout << " transcontent 内容字节数 = " << transcontent.size() << std::endl;std::cout << " transcontent GBK 内容[" << transcontent <<"]" << std::endl;std::cout << "====================================================" << std::endl;}{std::string filecontent;std::string transcontent;std::string gbkfilepath = "./test-file/utf-8.txt";readfile(gbkfilepath, filecontent);std::cout << " ./test-file/utf-8.txt 内容字节数 = " << filecontent.size() << std::endl;bool res = SegmentTransUtf8ToOther("GB18030", filecontent, transcontent, 1000);std::cout << " transcontent 内容字节数 = " << transcontent.size() << std::endl;std::cout << " transcontent GB18030 内容[" << transcontent << "]" << std::endl;std::cout << "====================================================" << std::endl;}{std::string filecontent;std::string transcontent;std::string gbkfilepath = "./test-file/utf-8.txt";readfile(gbkfilepath, filecontent);std::cout << " ./test-file/utf-8.txt 内容字节数 = " << filecontent.size() << std::endl;bool res = SegmentTransUtf8ToOther("GB2312", filecontent, transcontent, 1000);std::cout << " transcontent 内容字节数 = " << transcontent.size() << std::endl;std::cout << " transcontent GB2312 内容[" << transcontent << "]" << std::endl;std::cout << "====================================================" << std::endl;}return 0;}
相关文章:
[字符编码]windwos下使用libiconv转换编码格式(二)
在http://t.csdnimg.cn/PLUuz笔记中实现了常用编码格式转换的功能,但这还是一个demo。因为代码中向libiconv库函数传递的字符串是存放在堆空间中的(我也是从网上找例子测试,是否一定要开辟堆空间存放还有待考证),如果一次性转换的字节数很巨大的话,就会导致内存空间不足,进而引…...
textile 语法
1、文字修饰 修饰行内文字 字体样式textile 语法对应的 XHTML 语法实际显示效果加强*strong*<strong>strong</strong>strong强调_emphasis_<em>emphasis</em>emphasis加粗**bold**<b>bold</b>bold斜体__italics__<i>italics</i…...
【快速开发】使用SvelteKit
自我介绍 做一个简单介绍,酒架年近48 ,有20多年IT工作经历,目前在一家500强做企业架构.因为工作需要,另外也因为兴趣涉猎比较广,为了自己学习建立了三个博客,分别是【全球IT瞭望】,【…...
【docker笔记】docker常用命令
1、帮助启动类命令 1.1 启动、重启、查询当前状态、停止 systemctl start docker systemctl stop docker systemctl restart docker systemctl status docker1.2 设置开机启动 systemctl enable docker1.3 查看docker概要信息 docker info1.4 查看docker帮助文档 docker -…...
API 接口怎样设计才安全?
设计安全的API接口是确保应用程序和数据安全的重要方面之一。下面是一些设计安全的API接口的常见实践: 1. 身份验证和授权: 使用适当的身份验证机制,如OAuth、JWT或基本身份验证,以确保只有经过身份验证的用户可以访问API。实施…...
网站被CC攻击了怎么办?CC攻击有什么危害
网络爆炸性地发展,网络环境也日益复杂和开放,同时各种各样的恶意威胁和攻击日益增多,其中网站被CC也是常见的情况。 CC攻击有什么危害呢? 被CC会导致: 1.访问速度变慢:网站遭受CC攻击后,由于…...
Docker - 镜像 | 容器 日常开发常用指令 + 演示(一文通关)
目录 Docker 开发常用指令汇总 辅助命令 docker version docker info docker --help 镜像命令 查看镜像信息 下载镜像 搜索镜像 删除镜像 容器命令 查看运行中的容器 运行容器 停止、启动、重启、暂停、恢复容器 杀死容器 删除容器 查看容器日志 进入容器内部…...
要参加微软官方 Copilot 智能编程训练营了
GitHub Copilot 是由 GitHub、OpenAI 和 Microsoft 联合开发的生成式 AI 模型驱动的。 GitHub Copilot 分析用户正在编辑的文件及相关文件的上下文,并在编写代码时提供自动补全式的建议。 刚好下周要参加微软官方组织的 GitHub Copilot 工作坊-智能编程训练营&…...
Python入门学习篇(五)——列表字典
1 列表 1.1 定义 ①有序可重复的元素集合 ②可以存放不同类型的数据 ③个人理解:类似于java中的数组1.2 相关方法 1.2.1 获取列表长度 a 语法 len(列表名)b 示例代码 list2 [1, 2, "hello", 4] print(len(list2))c 运行结果 1.2.2 获取列表值 a 语法 列表名…...
React尝鲜
组件 React的组件就是一个js函数,函数内部return一个由jsx语法创建的html代码片段。 //MyComp.js export default function MyComp(){return (<h1>我是新组件MyComp</h1>) } 在需要引入组件的地方import导入组件,并放在相应位置 //App.js…...
锯齿云服务器租赁使用教程
首先登陆锯齿云账号 网盘上传数据集与代码 随后我们需要做的是将所需要的数据集与代码上传到网盘(也可以直接在租用服务器后将数据集与代码传到服务器的硬盘上,但这样做会消耗大量时间,造成资源浪费) 点击工作空间:…...
HarmonyOS和OpenHarmony的区别
1.概要 众所周知,鸿蒙是华为开发的一款分布式操作系统。因为开发系统,最重要的是集思广益,大家共同维护。为了在IOS和Android之间生存,鸿蒙的茁壮成长一定是需要开源,各方助力才能实现。 在这种思想上,…...
Redis Stream消息队列之基本语法与使用方式
前言 本文的主角是Redis Stream,它是Redis5.0版本新增加的数据结构,主要用于消息队列,提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证…...
制造行业定制软件解决方案——工业信息采集平台
摘要:针对目前企业在线检测数据信号种类繁多,缺乏统一监控人员和及时处置措施等问题。蓝鹏测控开发针对企业工业生产的在线数据的集中采集分析平台,通过该工业信息采集平台可将企业日常各种仪表设备能够得到数据进行集中分析处理存储…...
[python]用python实现对arxml文件的操作
目录 关键词平台说明一、背景二、方法2.1 库2.2 code 关键词 python、excel、DBC、openpyxl 平台说明 项目Valuepython版本3.6 一、背景 有时候需要批量处理arxml文件(ARXML 文件符合 AUTOSAR 4.0 标准),但是工作量太大,阔以考虑用python。 二、方…...
pdf 在线编辑
https://smallpdf.com/edit-pdf#rapp 参考 https://zh.wikihow.com/%E5%B0%86%E5%9B%BE%E5%83%8F%E6%8F%92%E5%85%A5PDF...
自然语言处理(NLP):理解语言,赋能未来
目录 前言1 什么是NLP2 NLP的用途3 发展历史4 NLP的基本任务4.1 词性标注(Part-of-Speech Tagging)4.2 命名实体识别(Named Entity Recognition)4.3 共指消解(Co-reference Resolution)4.4 依存关系分析&am…...
FastAPI使用loguru时,出现重复日志打印的解决方案
首先看图,发现每个日志都被打印了3条。其实这个和uvicorn日志打印的设计有关,在uvicorn中有多个logger,分别是uvicorn、uvicorn.error、uvicorn.access 而LOGGING默认有一个属性propagate,这个属性为True时,子日志记录…...
构建每个聚类的profile和deletion_mean特征
通过summarize_clusters函数构建每个聚类的protein[cluster_profile]和protein[cluster_deletion_mean]特征。目的是把extra_msa信息反映到msa中。 集成函数数据处理流程: sample_msa ->make_masked_msa -> nearest_neighbor_clusters -> summarize_clu…...
Milvus数据一致性介绍及选择方法
1、Milvus 时钟机制 Milvus 通过时间戳水印来保障读链路的一致性,如下图所示,在往消息队列插入数据时, Milvus 不光会为这些插入记录打上时间戳,还会不间断地插入同步时间戳,以图中同步时间戳 syncTs1 为例࿰…...
7.4.分块查找
一.分块查找的算法思想: 1.实例: 以上述图片的顺序表为例, 该顺序表的数据元素从整体来看是乱序的,但如果把这些数据元素分成一块一块的小区间, 第一个区间[0,1]索引上的数据元素都是小于等于10的, 第二…...
springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
(二)TensorRT-LLM | 模型导出(v0.20.0rc3)
0. 概述 上一节 对安装和使用有个基本介绍。根据这个 issue 的描述,后续 TensorRT-LLM 团队可能更专注于更新和维护 pytorch backend。但 tensorrt backend 作为先前一直开发的工作,其中包含了大量可以学习的地方。本文主要看看它导出模型的部分&#x…...
渗透实战PortSwigger靶场-XSS Lab 14:大多数标签和属性被阻止
<script>标签被拦截 我们需要把全部可用的 tag 和 event 进行暴力破解 XSS cheat sheet: https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 通过爆破发现body可以用 再把全部 events 放进去爆破 这些 event 全部可用 <body onres…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)
引言 在人工智能飞速发展的今天,大语言模型(Large Language Models, LLMs)已成为技术领域的焦点。从智能写作到代码生成,LLM 的应用场景不断扩展,深刻改变了我们的工作和生活方式。然而,理解这些模型的内部…...
