当前位置: 首页 > news >正文

【Qt】总体把握文本编码问题

在项目开发中,经常会遇到文本编码问题。文本编码知识非常基础,但对于新手来说,可能需要花费较长的时间去尝试,才能在脑海中建立对编码的正确认知。文本编码原理并不难,难的是在项目实践中掌握正确处理文本编码的方法。本文从项目实践出发,总结了项目中编码处理的相关经验,希望可以帮助基础比较薄弱的同学,快速建立对编码的基本认知,同时减少实际项目中踩坑的几率。

1. 从不同的视角看数据

1.1 计算机最底层视角

从计算机最底层的视角看,计算机中的数据,不管是寄存器中的数据,还是内存中的数据,还是磁盘上的文件数据,都是以0和1的二进制格式存放的。所以,一般在说二进制数据时候,是从计算机最底层的视角而言的。

1.2 计算机应用视角

应用程序处理计算机中的数据时,只有遵循数据创建者对数据格式的约定,对数据进行处理,才能正确提取出文件内容创建者所想要表达的信息。

文件创建者通常使用文件后缀名来标明文件内容格式。常见的文件格式后缀名有:.jpg、.txt、.mp4 等。

处理数据时,是否遵循数据格式约定,完全由应用程序决定,程序认为它是什么格式,就可以以什么格式对数据进行处理。如果使用和约定不一致的格式处理数据,那么从数据中提取出的信息极有可能是混乱的、无用的。例如,使用文本编辑器打开一张图像,最终文本编辑器的显示内容将是一堆乱码,无法阅读。实际项目中文本出现乱码问题也是这个原因。

2. 文本乱码问题分析

2.1 文本编码简介

对世界上所有符号、文字进行编号,产生一张字符表,这个表叫做“字符集”。这样一来,我们可以使用数字编号来表示字符,每个编号占用相同的字节数。因为世界上的字符很多,一般使用32位的无符号整型存储编号,总计大约可以表示42亿种字符。目前通用的字符集是Unicode字符集。

字符集中,有的字符使用频繁,有的字符使用不频繁,使用相同字节长度的数字编号会有些浪费存储空间。改进的存储方案类似于哈夫曼编码:将使用频繁的字符用更少的字节数表示,使用不频繁的字符,用较长的字节数表示。经过优化的存储方式,叫做“文本编码”。

文本有很多种编码格式,如GBK,GB18030,UTF-8等等,目前最常用的文本编码格式是UTF-8。编码的具体实现不是本文的主要内容,所以不作展开。

2.1 文本乱码原因

由于计算机最早由老外发明,所以各种文本编码格式对英文的兼容性最好,所以英文通常不会乱码。而同一个中文汉字,用不同的文本编码格式进行编码后,对应的二进制数据是不同的。反过来,同一段文本数据,使用不同的编码进行文本解码,则会解析出来截然不同的文本内容。

总的来说,文本乱码有两个原因:

  • 一段数据本身就不是文本数据,可能是图像数据,也可能是视频数据等非文本类型的数据,如果将其视作文本进行解码,必然会导致乱码。
  • 我们编写的应用程序,没有采用正确的文本编码格式对文本数据进行解码,导致输出的文本就会出现严重混乱,即乱码,进而导致程序处理结果偏离预期,出现错误。

2.2 文本乱码的处理思路

根据文本乱码的原因,我们在遇到乱码问题时,需要对以下问题进行排查:

  • 检查文本数据的产生、存储、传输过程是否出错;
  • 尝试与文本内容提供者核对双方文本编码格式是否一致。
  • 尝试猜测文本编码,这种方法不是很可靠,但值得一试。

2.3 Qt对文本编码的处理支持

Qt提供了很多关于文本编码解码的函数及类接口。如下所示:

接口说明
QString::fromXXX()系列QString的静态函数如QString::fromLocal8Bit,QString::fromUtf8,QString::fromLatin1等,提供了常用的文本解码接口。解码出来的结果统一为UTF-16编码格式,保存在QString缓冲区中。
QString::toXXX()系列QString的静态函数如QString::toLocal8Bit,QString::toUtf8,QString::toLatin1等,提供了常用的文本编码接口。编码后的文本数据,保存在QByteArray缓冲区中。
QTextCodec类提供了更强大的编码转换功能,可以通过文本编码名称获取对应的文本编解码器。可以实现各种文本编码之间的编码转换。

这里必须提一下QByteArray和QString的区别。

类型区别
QByteArrayQByteArray中的数据,仅仅是二进制数据,可以把它看作是一个内存区,仅此而已。它用于计算机底层视角下的数据存储。可以根据业务需要,确定数据格式类型后,再进行数据处理。
QString存储文本。它用于计算机应用视角下的文本内容存储。QString可直接在界面内容显示、文本信息处理等应用层面使用。

项目中,我们通常使用QByteArray缓存获取到的数据。如果确定QByteArray中存储的数据是文本,那么下一步需要确定文本的编码格式,最后,可以使用 QString或QTextCodec提供的文本编码转换接口对其中的数据进行编码转换,最终得到QString。反过来,我们也可以将QString保存成多种文本编码格式,用于保存或传输。

3. 容易出现文本乱码的应用场景

3.1 处理含有中文的文件

当我们读写文本文件时,必须使用协商一致的文本编码。否则会导致读取的数据产生严重乱码,影响程序稳定性,甚至造成严重后果。不管读文件还是写文件,都要考虑文本编码问题。

3.2 含有中文的代码文件乱码

使用Qt+MSVC在Windows上进行开发时,经常会遇到代码编译不通过,或者程序运行出现乱码的问题。原因是MSVC默认认为源代码是GBK编码。在Qt .pro文件中打开以下编译开关,告诉MSVC编译器,使用UTF-8格式处理源码文本即可解决:

QMAKE_C_FLAGS += /utf-8
QMAKE_CXX_FLAGS += /utf-8

3.3 处理含有中文的通信数据

在进行数据通信的时候,如果通信协议中包含中文,而通信双方又没有对文本编码做出明确约定,那么很有可能会出现乱码的问题。解决办法是,通信双方通信协议中提前约定好的统一的文本编码,一般可以使用UTF-8编码。

4. 总结

牢记:只要我们按文本处理数据,就要考虑数据格式和文本编码。绝不可忽略文本编码直接进行文本处理。

除Qt开发外,在其他软件开发技术中也需要注意文本编码问题。

本文主要讲解了文本编码的相关处理经验和总体逻辑框架。文本编码相关内容很多,项目中可能会出现各种各样的问题,需要结合本文讲解的总体思路,深入问题综合分析。


本文原创发布于 Qt未来工程师。

相关文章:

【Qt】总体把握文本编码问题

在项目开发中,经常会遇到文本编码问题。文本编码知识非常基础,但对于新手来说,可能需要花费较长的时间去尝试,才能在脑海中建立对编码的正确认知。文本编码原理并不难,难的是在项目实践中掌握正确处理文本编码的方法。…...

Linux命令(77)之curl

linux命令之curl 1.curl介绍 linux命令之curl是一款强大的http命令行工具&#xff0c;它支持文件的上传和下载&#xff0c;是综合传输工具。 2.curl用法 curl [参数] [url] curl参数 参数说明-C断点续传-o <filename>把输出写到filename文件中-x在给定的端口上使用HT…...

详解 sudo usermod -aG docker majn

这个命令涉及到几个 Linux 系统管理的基础概念&#xff0c;包括 sudo、usermod 和用户组管理。我们可以逐一地解析它们&#xff1a; sudo: sudo&#xff08;superuser do&#xff09;允许一个已经被授权的用户以超级用户或其他用户的身份执行一个命令。当使用 sudo 前缀一个命令…...

大数据课程L2——网站流量项目的算法分析数据处理

文章作者邮箱:yugongshiye@sina.cn 地址:广东惠州 ▲ 本章节目的 ⚪ 了解网站流量项目的算法分析; ⚪ 了解网站流量项目的数据处理; 一、项目的算法分析 1. 概述 网站流量统计是改进网站服务的重要手段之一,通过获取用户在网站的行为,可以分析出哪些内…...

jar包或exe程序设置为windows服务

最近在使用java和python制作客户端时突发奇想&#xff0c;是否能够通过一种方法来讲jar包和exe程序打包成windows服务呢&#xff1f;简单了解了一下是可以的。 首先要用到的是winSW&#xff0c;制作windows服务的过程非常简单&#xff0c;仅需几步制作完成&#xff0c;也不需要…...

数据结构--- 树

(一)知识补充 定义 树是一种数据结构,它是由n(n≥0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。​ 它具有以下的特点: 每个节点有零个或多个子节点; 没有父节点的节点称为根节点;每一个非根…...

两个pdf文件合并为一个怎么操作?分享pdf合并操作步骤

不管是初入职场的小白&#xff0c;还是久经职场的高手&#xff0c;都必须深入了解pdf&#xff0c;特别是关于pdf的各种操作&#xff0c;如编辑、合并、压缩等操作&#xff0c;其中合并是这么多操作里面必需懂的技能之一&#xff0c;但是很多人还是不知道两个pdf文件合并为一个怎…...

Zookeeper简述

数新网络-让每个人享受数据的价值 官网现已全新升级—欢迎访问&#xff01; 前 言 ZooKeeper是一个开源的、高可用的、分布式的协调服务&#xff0c;由Apache软件基金会维护。它旨在帮助管理和协调分布式系统和应用程序&#xff0c;提供了一个可靠的平台&#xff0c;用于处理…...

1、Flutter移动端App实战教程【环境配置、模拟器配置】

一、概述 Flutter是Google用以帮助开发者在IOS和Android 两个平台开发高质量原生UI的移动SDK&#xff0c;一份代码可以同时生成IOS和Android两个高性能、高保真的应用程序。 二、渲染机制 之所以说Flutter能够达到可以媲美甚至超越原生的体验&#xff0c;主要在于其拥有高性…...

stride与padding对输出尺寸的计算

公式&#xff1a; 练习&#xff1a; 图1&#xff1a; input4&#xff0c;filter3&#xff0c;padding0&#xff0c;stride1 output2 图2&#xff1a; input5&#xff0c;filter3&#xff0c;padding0&#xff0c;stride2 output2 图3&#xff1a; input6&#xff0c;filter3&am…...

Excel VSTO开发2 -建立Excel VSTO项目

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 2 建立Excel VSTO项目 新建项目&#xff0c;选择Excel 2013和2016 VSTO外接程序。输入项目名称&#xff08;本示例的项目名称为&am…...

chrome插件:一个基于webpack + react的chrome 插件项目模板

项目结构 $ tree -L 1 . ├── README.md ├── node_modules # npm依赖 ├── package.json # 详细依赖 ├── pnpm-lock.yaml ├── public # 里边包含dist&#xff0c;安装的时候安装这个目录即可 ├── src …...

Vue:组件缓存

组件缓存 keep-alive 文章目录 组件缓存 keep-alive一、keep-alive是什么二、keep-alive优点三、问题四、解决方案五、代码示例 六、回顾一下钩子七、总结 一、keep-alive是什么 keep-alive是Vue中的一个内置组件&#xff0c;会缓存不活动的组件实例。并不会销毁组件&#xff…...

【C++】DICOM医学影像工作站PACS源码

PACS即影像存档与传输系统&#xff0c;是医学影像、数字化图像技术、计算机技术和网络通讯技术相结合的产物&#xff0c;是处理各种医学影像信息的采集、存储、报告、输出、管理、查询的计算机应用程序。 PACS是基于DICOM标准的医学影像管理系统&#xff0c;其模块覆盖了从影像…...

UDP的可靠性传输2

系列文章目录 第一章 UDP的可靠性传输-理论篇&#xff08;一&#xff09; 第二章 UDP的可靠性传输-理论篇&#xff08;二&#xff09; 文章目录 系列文章目录三、流量控制RTORTT流量控制1.如何控制流量2. 发送方何时在发送数据3.流程图 拥塞控制1.慢启动 总结1.拥塞控制和流量…...

《Java程序设计》实验报告

实验内容&#xff1a;面向对象程序设计 1、定一个名为Person的类&#xff0c;其中含有一个String类型的成员变量name和一个int类型的成员变量age&#xff0c; 分别为这两个变量定义访问方法和修改方法&#xff0c;另外再为该类定义一个名为speak的方法&#xff0c; 在其中输出n…...

数据可视化、BI和数字孪生软件:用途和特点对比

在现代企业和科技领域&#xff0c;数据起着至关重要的作用。为了更好地管理和理解数据&#xff0c;不同类型的软件工具应运而生&#xff0c;其中包括数据可视化软件、BI&#xff08;Business Intelligence&#xff09;软件和数字孪生软件。虽然它们都涉及数据&#xff0c;但在功…...

Ros noetic 机器人坐标记录运动路径和发布 实战教程(C)

前言: 承接上一篇博文本文将编写并记录上文中详细的工程项目,用于保存小车的运动路径,生成对应的csv,和加载所保存的路径到实际的Rviz中,本文将开源完整的工程项目,工程结构如下: 工程原码位于文章末尾: 路径存储: waypoint_saver 用于存储 waypoint 的节点 waypo…...

Linux入门之多线程|线程的同步|生产消费模型

文章目录 一、多线程的同步 1.概念 2.条件变量 2.1条件变量概念 2.2条件变量接口 1.条件变量初始化 2.等待条件满足 3.唤醒等待 3.销毁条件变量 2.3条件变量demo 二、生产消费模型 1.生产消费模型 2.基于BlockQueue的生产者消费者模型 3.基于C用条件变量和互斥锁实…...

MATLAB解析和保存ini文件

1. 将ini文件转换成struct结构体 function data ini2struct(filename)fid fopen(filename, r);if fid -1error(Unable to open file %s., filename);enddata struct();section ;while ~feof(fid)line fgetl(fid);line strtrim(line);% 如果是注释行或者空行&#xff0c…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?

Redis 的发布订阅&#xff08;Pub/Sub&#xff09;模式与专业的 MQ&#xff08;Message Queue&#xff09;如 Kafka、RabbitMQ 进行比较&#xff0c;核心的权衡点在于&#xff1a;简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...

STM32---外部32.768K晶振(LSE)无法起振问题

晶振是否起振主要就检查两个1、晶振与MCU是否兼容&#xff1b;2、晶振的负载电容是否匹配 目录 一、判断晶振与MCU是否兼容 二、判断负载电容是否匹配 1. 晶振负载电容&#xff08;CL&#xff09;与匹配电容&#xff08;CL1、CL2&#xff09;的关系 2. 如何选择 CL1 和 CL…...