QtC++技术分析2 - 标准库与 QT 字符串处理

news/2024/12/2 22:34:10/

目录

    • 标准库与 QT 字符串处理
      • 标准库类模板
        • 模板参数与构造函数
        • basic_string 的其他成员函数
      • QString
        • QString 特性
        • QByteArray
    • 国际化与区域文化
      • 区域文化
      • facet
        • numpunct
        • time_get
        • time_put
        • codecvt

标准库与 QT 字符串处理


标准库类模板

C++使用类模板 basic_string 来存放字符串数据,并提供了一组成员函数来处理该字符串

basic_string 还具有一个明显的优势:自动内存管理功能


模板参数与构造函数

类 string 及 wstring 是 basic_string 特化的结果

typedef  basic_string<char>  string;
typedef  basic_string<wchar_t>  wstring;

basic_string 常见的构造函数及其使用方法

对于 wchar_t 类型的 basic_string,最好在字符串常量的前面加上前缀“L”

#include <string>
#include <iostream>
using namespace std;
int main()
{basic_string<char> s1;basic_string<char> s2 ("hello world");basic_string<char> s3 ("hello world", 5);basic_string<char> s4 ( s2, 6, 5);cout << s1 << endl << s2 << endl << s3 << endl << s4 << endl;// 加了L前缀的字符串basic_string<wchar_t> ws (L"得友难失友易(A friend is easier lost thanfound)");wcout.imbue(locale("chs"));wcout << "size is: " << sizeof(ws[7]) << endl << ws << endl;
}

basic_string 的其他成员函数

c_str() 该函数返回一个指针,指向 basic_string 中存放的字符串数据
对于 string 类型,该函数返回char *;
对于 wstring 类型,该函数返回wchar_t *;

basic_string 的类模板存在一个专门存放字符串长度的成员变量,通过 length()直接获取字符串长度,可以相对于 strlen()方法获取长度节省很多时间


QString

QString 能对 Unicode 字符串进行拼接、查找等操作

不建议使用 basic_string 中的 wstring 替换掉 QString,因为前者对于标点符号判断等其他操作支持较差,而后者封装完善便于拿来即用


QString 特性

利用 fromLocal8Bit(),将该字符串转换为 Unicode 编码的字符

QString 的成员函数 data() 返回一个指针,指向 QChar 序列

QString 自带的字符编码转换功能展示:

// 定义 main 函数
int main()
{// 定义一个 char* 类型的字符串 humor,包含了英文和中文字符char * humor = "Your future depends on your dream. So go to sleep.\n""你的梦想决定你的未来,所以睡觉去吧。";// 将 humor 转换为 QString 类型的字符串 qs,使用 fromLocal8Bit 方法将 humor 中的字符转换为本地编码QString qs = QString::fromLocal8Bit(humor);// 将 qs 转换为 QByteArray 类型的数据 data,使用 toUtf8 方法将 qs 中的字符转换为 UTF-8 编码QByteArray data = qs.toUtf8();// 打开文件 utf8.txt,以二进制模式写入数据ofstream of("utf8.txt", ios::binary);// 将 data 中的数据写入文件,使用 data.data() 获取数据指针,data.length() 获取数据长度of.write(data.data(), data.length());
}

QByteArray

QByteArray 被用来存放长度可变的字节序列,其中的字节序列被存放在一个地址连续的内存块中

该类总会在字节序列的末尾添加一个额外的“\0”字符


国际化与区域文化


区域文化

C++标准库提供了类 locale 以及 facet ,分别用来描述某个区域的区域文化以及文化刻面

所有流对象都会共享一个全局的 locale 对象

一般的,开发者不需要知道 facet 的原理,直接使用 locale 即可实现区域文焕转换设定
下方代码展示了使用 cout 输出区域文化为德国的文本

#include <iostream>
#include <locale>
using namespace std;
int main( )
{double x = 1234567.123456;cout.imbue( locale( "German_germany" ) );①cout << fixed << x << endl;
}

facet

每个 facet 子类描述某个文化刻面。C++标准库定义了 12 个常用的 facet 子类,来刻画时间、货币等表达方式

facet 对象不能够单独存在,它们必须隶属于某个 locale 对象
通过调用函数模板 use_facet<>可以获得一个 locale 对象中某个 facet 对象的引用


numpunct

numpunct 是 facet 的一个子类,可以通过 use_facet 获取 facet 对象后对其实例化得到 numpunct 对象

#include <locale>
#include <iostream>// 定义 main 函数
int main()
{// 创建一个 locale 对象 os_locale,使用默认本地化设置locale os_locale("");// 获取 os_locale 的数字标点符号,使用 use_facet 方法获取 numpunct<char> 类型的 facet 对象const numpunct<char>& np = use_facet<numpunct<char>>(os_locale);// 输出数字标点符号的信息,包括小数点、千位分隔符、true/false 字符串等std::cout << "number punctuation of " << os_locale.name() << std::endl;std::cout << np.decimal_point() << " "<< np.thousands_sep() << " "<< np.falsename() << " " << np.truename() << std::endl;// 获取数字分组信息,输出每个分组的长度std::string group = np.grouping();for (int i = 0; i < group.length(); i++) {std::cout << i << "th grouping is: " << (int)group[i] << std::endl;}
}

time_get

类模板 time_get 对一个表示日期和时间的字符序列进行解析,将其中的信息存放在结构体 tm 中

类模板 time_get 的基本使用方法

#include <iostream>
#include <sstream>
#include <locale>// 定义 main 函数
int main()
{// 创建一个 locale 对象 loc,使用默认本地化设置locale loc;// 获取 loc 的 time_get facet 对象 tg,用于解析时间信息const time_get<char>& tg = use_facet<time_get<char>>(loc);// 获取日期的顺序信息,使用 date_order() 方法获取日期的顺序,返回值为整数int idx = tg.date_order();// 输出本地化设置的名称和日期的顺序信息,message 数组用于将整数转换为字符串char *message[] = {"no_order", "dmy", "mdy", "ymd", "ydm"};std::cout << loc.name() << std::endl << "date order " << message[idx] << std::endl;// 解析时间信息,使用 istringstream 类创建一个输入流 iss,包含了要解析的时间字符串 "10:26:00"std::ios::iostate state = 0;std::istringstream iss("10:26:00");// 创建一个 istreambuf_iterator 对象 itbegin,指向 iss 的开头std::istreambuf_iterator<char> itbegin(iss);// 创建一个 istreambuf_iterator 对象 itend,指向 iss 的结尾std::istreambuf_iterator<char> itend;// 创建一个 tm 结构体对象 time,用于存储解析后的时间信息std::tm time;// 使用 time_get 的 get_time 方法解析时间信息,将结果存储在 time 中tg.get_time(itbegin, itend, iss, state, &time);// 输出解析后的时间信息std::cout << time.tm_hour << ":" << time.tm_min << ":" << time.tm_sec << std::endl;
}

time_put

类模板 time_put 将存放在结构体 tm 中的日期和时间信息以某种特定的格式转化为一个字符序列

使用场景较少,不浪费过多笔墨介绍该类模板


codecvt

类模板 codecvt 将某一种编码的字符串转换为另外一种编码的字符串

此为对应模板以及三个模板参数的含义

  • internT 表示一个字符串在计算机内部的编码类型
  • externT 表示该字符串在外部存储设备(比如文件系统)中的编码类型
  • stateT 是一个表示转换状态的类型

template <class internT,class externT,class stateT> codecvt


类模板 codecvt 的成员函数 in 的功能

#include <iostream>
#include <locale>// 定义 main 函数
int main()
{// 定义 codecvt 类型的别名 cvt_typetypedef codecvt<wchar_t, char, mbstate_t> cvt_type;// 创建一个 locale 对象 loc,使用默认本地化设置locale loc;// 获取 loc 的 codecvt facet 对象 cvt,用于字符编码转换const cvt_type& cvt = use_facet<cvt_type>(loc);// 定义字符数组,src 为待转换的字符串,dst 为存储转换结果的字符串const int size = 20;const char* p1, src[size] = "hello world!";wchar_t* p2, dst[size];// 定义 mbstate_t 对象 state,用于存储转换过程中的状态信息mbstate_t state;// 使用 cvt.in() 方法将 src 中的字符转换为 dst 中的宽字符cvt_type::result result = cvt.in(state,src, src + size, p1,dst, dst + size, p2);// 如果转换成功,输出转换结果if (result == cvt_type::ok) {std::wcout << dst << std::endl;}return 0;
}


http://www.ppmy.cn/news/976643.html

相关文章

去除 idea warn Raw use of parameterized class ‘Map‘

去除 idea warn Raw use of parameterized class ‘Map’ 文档&#xff1a;Raw use of parameterized class ‘Map’… 链接&#xff1a;http://note.youdao.com/noteshare?id99bf4003db8cc5ae9813ee11e58c4d13&sub5856371AEFA740AF8FA4D8935B4F6912 添加链接描述 public…

一个神奇的框架——Skins换肤框架

作者&#xff1a;dora 为什么会有换肤的需求 app的换肤&#xff0c;可以降低app用户的审美疲劳。再好的UI设计&#xff0c;一直不变的话&#xff0c;也会对用户体验大打折扣&#xff0c;即使表面上不说&#xff0c;但心里或多或少会有些难受。所以app的界面要适当的改版啊&…

Socket基本原理详解

socket的概念 故事要从一个插头说起。 插头与插座 当我将插头插入插座&#xff0c;那看起来就像是将两者连起来了。 风扇与电力系统建立"连接" 而插座的英文&#xff0c;又叫socket。 巧了&#xff0c;我们程序员搞网络编程时也会用到一个叫socket的东西。 其实两者…

SQL 简介

SQL 简介 简介 SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;是一种用于管理和操作关系型数据库的标准化语言。它允许用户通过使用各种指令来创建、修改和查询数据库中的数据。 SQL具有几个主要组成部分&#xff1a; 数据定义语言&#…

从零实现深度学习框架——RNN实现支持PackedSequence

引言 本着“凡我不能创造的,我就不能理解”的思想,本系列文章会基于纯Python以及NumPy从零创建自己的深度学习框架,该框架类似PyTorch能实现自动求导。 💡系列文章完整目录: 👉点此👈 要深入理解深度学习,从零开始创建的经验非常重要,从自己可以理解的角度出发,尽…

超详细,自动化测试allure测试报告实战(总结)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 allure可以输出非…

Linux系统进程概念详解

这里写目录标题 冯诺依曼体系结构操作系统(Operator System)1.概念2.目的3.管理4.系统调用和库函数概念 进程1.概念2.描述进程-PCB3.查看进程4.通过系统调用获取进程标示符5.通过系统调用创建进程-fork 进程状态1.Linux内核源代码2.进程状态查看 进程优先级1.基本概念2.查看系统…

Jmeter接口/性能测试,Jmeter使用教程(超细整理)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、线程组 线程组…