当前位置: 首页 > 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…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

#Uniapp篇:chrome调试unapp适配

chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器&#xff1a;Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...