QString

目录

1 toInt()

(1)qt_strtoll()

(2) qstrtoll()

(3)bytearrayToLongLong()

(4)toIntegral_helper


 

1 toInt()

下面是toInt()函数的内部实现源码

QString str("16");
int b  = str.toInt();
//toInt
int QString::toInt(bool *ok, int base) const
{return toIntegral_helper<int>(constData(), size(), ok, base);
}
//toIntegral_helpertemplate <typename T> staticT toIntegral_helper(const QChar *data, int len, bool *ok, int base){// ### Qt6: use std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::typeconst bool isUnsigned = T(0) < T(-1);typedef typename QtPrivate::QConditional<isUnsigned, qulonglong, qlonglong>::Type Int64;typedef typename QtPrivate::QConditional<isUnsigned, uint, int>::Type Int32;// we select the right overload by casting size() to int or uintInt64 val = toIntegral_helper(data, Int32(len), ok, base);if (T(val) != val) {if (ok)*ok = false;val = 0;}return T(val);}
//toIntegral_helper
qlonglong QString::toIntegral_helper(const QChar *data, int len, bool *ok, int base)
{
#if defined(QT_CHECK_RANGE)if (base != 0 && (base < 2 || base > 36)) {qWarning("QString::toULongLong: Invalid base (%d)", base);base = 10;}
#endifreturn QLocaleData::c()->stringToLongLong(QStringView(data, len), base, ok, QLocale::RejectGroupSeparator);
}
//stringToLongLong
qlonglong QLocaleData::stringToLongLong(QStringView str, int base, bool *ok,QLocale::NumberOptions number_options) const
{CharBuff buff;if (!numberToCLocale(str, number_options, &buff)) {if (ok != nullptr)*ok = false;return 0;}return bytearrayToLongLong(buff.constData(), base, ok);
}
//bytearrayToLongLong
qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok)
{bool _ok;const char *endptr;if (*num == '\0') {if (ok != nullptr)*ok = false;return 0;}qlonglong l = qstrtoll(num, &endptr, base, &_ok);if (!_ok) {if (ok != nullptr)*ok = false;return 0;}if (*endptr != '\0') {while (ascii_isspace(*endptr))++endptr;}if (*endptr != '\0') {// we stopped at a non-digit character after converting some digitsif (ok != nullptr)*ok = false;return 0;}if (ok != nullptr)*ok = true;return l;
}
//qstrtoll
long long
qstrtoll(const char * nptr, const char **endptr, int base, bool *ok)
{*ok = true;errno = 0;char *endptr2 = 0;long long result = qt_strtoll(nptr, &endptr2, base);if (endptr)*endptr = endptr2;if ((result == 0 || result == std::numeric_limits<long long>::min()|| result == std::numeric_limits<long long>::max())&& (errno || nptr == endptr2)) {*ok = false;return 0;}return result;
}
//qt_strtoll
/** Convert a string to a long long integer.** Assumes that the upper and lower case* alphabets and digits are each contiguous.*/
long long
qt_strtoll(const char * nptr, char **endptr, int base)
{const char *s;unsigned long long acc;char c;unsigned long long cutoff;int neg, any, cutlim;/** Skip white space and pick up leading +/- sign if any.* If base is 0, allow 0x for hex and 0 for octal, else* assume decimal; if base is already 16, allow 0x.*/s = nptr;do {c = *s++;} while (ascii_isspace(c));if (c == '-') {neg = 1;c = *s++;} else {neg = 0;if (c == '+')c = *s++;}if ((base == 0 || base == 16) &&c == '0' && (*s == 'x' || *s == 'X') &&((s[1] >= '0' && s[1] <= '9') ||(s[1] >= 'A' && s[1] <= 'F') ||(s[1] >= 'a' && s[1] <= 'f'))) {c = s[1];s += 2;base = 16;}if (base == 0)base = c == '0' ? 8 : 10;acc = any = 0;if (base < 2 || base > 36)goto noconv;/** Compute the cutoff value between legal numbers and illegal* numbers.  That is the largest legal value, divided by the* base.  An input number that is greater than this value, if* followed by a legal input character, is too big.  One that* is equal to this value may be valid or not; the limit* between valid and invalid numbers is then based on the last* digit.  For instance, if the range for quads is* [-9223372036854775808..9223372036854775807] and the input base* is 10, cutoff will be set to 922337203685477580 and cutlim to* either 7 (neg==0) or 8 (neg==1), meaning that if we have* accumulated a value > 922337203685477580, or equal but the* next digit is > 7 (or 8), the number is too big, and we will* return a range error.** Set 'any' if any `digits' consumed; make it negative to indicate* overflow.*/cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX: LLONG_MAX;cutlim = cutoff % base;cutoff /= base;for ( ; ; c = *s++) {if (c >= '0' && c <= '9')c -= '0';else if (c >= 'A' && c <= 'Z')c -= 'A' - 10;else if (c >= 'a' && c <= 'z')c -= 'a' - 10;elsebreak;if (c >= base)break;if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))any = -1;else {any = 1;acc *= base;acc += c;}}if (any < 0) {acc = neg ? LLONG_MIN : LLONG_MAX;errno = ERANGE;} else if (!any) {
noconv:errno = EINVAL;} else if (neg)acc = (unsigned long long) -(long long)acc;if (endptr != NULL)*endptr = const_cast<char *>(any ? s - 1 : nptr);return (acc);
}

从后往前分析

(1)qt_strtoll()
// 这是一个将字符串转换为长整数的函数,它接受三个参数:  
// 1. 一个指向要转换的字符串的指针 nptr。  
// 2. 一个指向字符的指针 endptr,如果转换成功,endptr 将被设置为字符串中第一个无法被转换的字符的位置。  
// 3. 一个整数 base,用于指定数字的基数,例如十进制、十六进制等。  
long long qt_strtoll(const char * nptr, char **endptr, int base) {  const char *s;  // s 用于保存字符串的当前位置  unsigned long long acc;  // acc 用于保存累积的转换结果  char c;  // c 用于保存当前字符  unsigned long long cutoff;  // cutoff 用于保存转换的上限(基于正负和基数)  int neg, any, cutlim;  // neg 用于标记数字是否为负数,any 用于标记是否有字符被成功转换,cutlim 用于保存累积的上限(基于基数)  // 跳过前导空格并获取可能存在的正负号  // 如果 base 为 0,允许使用 '0x' 表示十六进制,'0' 表示八进制,否则默认为十进制;如果 base 已经为 16,允许使用 '0x'。  // (以上注释内容是针对原文代码的逐行注释,所以这里不再翻译成英文)  // 此处通过一个 do-while 循环来跳过前导空格  // c 是当前的字符,通过递增 s 来获取下一个字符  s = nptr;  // 设置 s 为字符串的起始位置  do {  c = *s++;  // 获取下一个字符并递增 s  } while (ascii_isspace(c));  // 当 c 是空格字符时继续循环  // 如果 c 是 '-',设置 neg 为 1,并将 c 设置为下一个字符  // 如果 c 是 '+',设置 neg 为 0,并将 c 设置为下一个字符  if (c == '-') {  neg = 1;  // 设置 neg 为 1  c = *s++;  // 设置 c 为下一个字符并递增 s  } else {  neg = 0;  // 设置 neg 为 0  if (c == '+')   // 如果 c 是 '+',则设置 c 为下一个字符并递增 s  c = *s++;  // 设置 c 为下一个字符并递增 s  }  // 如果 c 是 '0',并且接下来的字符是 'x' 或 'X',并且接下来的字符是十六进制数字(0-9, A-F 或 a-f),则将 base 设置为 16,并设置 c 为接下来的字符并递增 s。  if ((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X') && ((s[1] >= '0' && s[1] <= '9') || (s[1] >= 'A' && s[1] <= 'F') || (s[1] >= 'a' && s[1] <= 'f'))) {  c = s[1];  // 设置 c 为接下来的字符并递增 s  s += 2;  // 将 s 向前移动两个位置(跳过 '0x' 或 '0X')  base = 16;  // 设置 base 为 16  }
// 如果 base 是 0,则根据 c 的值将 base 设置回十进制。如果 c 是 '0',则将 base 设置回八进制;否则将 base 设置回十进制。  if (base == 0) {  // 如果 base 是 0,则进行以下判断来设置 base 的值  base = (c == '0') ? 8 : 10;  // 如果 c 是 '0',则将 base 设置回八进制;否则将 base 设置回十进制。同时设置 c 为接下来的字符并递增 s。  } acc = 0; // 设置累积结果为0any = 0; // 设置任何字符被成功转换的标志为0cutoff = neg ? (unsigned long long)-(LLONG_MIN + LLONG_MAX) + LLONG_MAX : LLONG_MAX; // 设置转换的上下限为正负的最大值cutlim = cutoff % base; // 计算转换的上下限除以基数的结果cutoff /= base; // 将转换的上下限除以基数得到新的上限
// 根据标志判断是否发生了溢出,如果溢出,则将累积结果设置为相应的最小值或最大值,并设置errno为ERANGEif (any < 0) {acc = neg ? LLONG_MIN : LLONG_MAX; // 设置累积结果为正负的最大值errno = ERANGE; // 设置errno为ERANGE,表示溢出} else if (!any) { // 如果没有任何字符被成功转换,则设置errno为EINVALerrno = EINVAL; // 设置errno为EINVAL,表示无效的输入} 
(2) qstrtoll()
long long qstrtoll(const char * nptr, const char **endptr, int base, bool *ok)  
// 定义一个名为qstrtoll的函数,该函数将一个字符串转换为长整数。参数包括:要转换的字符串nptr,结束字符的指针endptr,转换的进制base,和一个指向布尔值的指针ok。  {  *ok = true;  // 初始化ok为true,表示转换过程开始时没有错误。  errno = 0;  // 初始化errno为0,用于记录可能发生的错误。  char *endptr2 = 0;  // 定义一个新的字符指针endptr2并将其初始化为0。它用于存储转换结束的位置。  long long result = qt_strtoll(nptr, &endptr2, base);  // 调用qt_strtoll函数进行实际的转换操作。将转换结果存储在result变量中,并将结束位置的指针存储在endptr2中。  if (endptr)  // 检查endptr是否为非空指针。如果是,则执行下面的代码块。  *endptr = endptr2;  // 将endptr指向的位置设置为转换结束的位置。  if ((result == 0 || result == std::numeric_limits<long long>::min()  // 检查result是否为0或者等于long long的最小值。如果是,则执行下面的代码块。  || result == std::numeric_limits<long long>::max())  // 或者等于long long的最大值。如果是,则执行下面的代码块。  && (errno || nptr == endptr2)) {  // 检查errno是否为非零值或者nptr是否等于endptr2。如果是,则执行下面的代码块。  *ok = false;  // 将ok设置为false,表示发生了错误。  return 0;  // 返回0,表示转换失败。  }  return result;  // 返回转换结果result。  
}
(3)bytearrayToLongLong()
// qlonglong QLocaleData::bytearrayToLongLong(const char *num, int base, bool *ok)  
// 定义一个名为bytearrayToLongLong的成员函数,该函数属于QLocaleData类,用于将字符数组转换为长整型数。  
// 输入参数包括:一个指向字符数组的指针num,表示要转换的字符串;一个int型的base,表示转换的进制;一个指向布尔值的指针ok,用于返回转换是否成功的信息。  {  // 定义一个局部布尔变量_ok,用于存储转换是否成功的信息。  bool _ok;  // 定义一个指向字符的指针endptr,用于存储转换结束的位置。  const char *endptr;  // 检查输入的字符串是否为空,如果为空则返回错误。  if (*num == '\0') {  // 如果ok不为空,则将其设置为false并返回0。  if (ok != nullptr)  *ok = false;  // 返回0,表示转换失败。  return 0;  }  // 调用qstrtoll函数将字符串转换为长整型数,并将转换结果存储在l中,转换结束的位置存储在endptr中,转换的结果存储在_ok中。  qlonglong l = qstrtoll(num, &endptr, base, &_ok);  // 如果转换失败,则返回错误。  if (!_ok) {  // 如果ok不为空,则将其设置为false并返回0。  if (ok != nullptr)  *ok = false;  // 返回0,表示转换失败。  return 0;  }  // 检查转换结束的位置是否为字符串的末尾,如果不是,则跳过之后的空白字符。  if (*endptr != '\0') {  while (ascii_isspace(*endptr))  ++endptr;  }  // 如果转换结束的位置不是字符串的末尾,说明在转换完一些数字之后遇到了非数字字符。  if (*endptr != '\0') {  // 在转换了一些数字之后遇到了一个非数字字符,设置ok为false并返回错误。  // we stopped at a non-digit character after converting some digits  if (ok != nullptr)  *ok = false;  // 返回0,表示转换失败。  return 0;  }  // 设置ok为true,表示转换成功。  if (ok != nullptr)  *ok = true;  // 返回转换结果。  return l;  
}
(4)toIntegral_helper
// T toIntegral_helper(const QChar *data, int len, bool *ok, int base) 函数接受四个参数:  
// 1. const QChar *data: 一个指向字符数据的指针,这些数据应该是要转换的数字字符串。  
// 2. int len: 字符数据的长度。  
// 3. bool *ok: 一个指向布尔值的指针,用于指示转换是否成功。如果转换成功,它将设置为true,否则设置为false。  
// 4. int base: 转换的基数,例如十进制、十六进制等。  {  // ### Qt6: use std::conditional<std::is_unsigned<T>::value, qulonglong, qlonglong>::type  // 在Qt6中,建议使用std::conditional来选择正确的类型。如果T是无符号整数类型,选择qulonglong,否则选择qlonglong。  const bool isUnsigned = T(0) < T(-1); // 判断T是否是无符号整数类型,如果是,isUnsigned为true,否则为false。  // 使用std::conditional来选择正确的类型。如果是无符号整数,选择qulonglong,否则选择qlonglong。  typedef typename QtPrivate::QConditional<isUnsigned, qulonglong, qlonglong>::Type Int64;   // 使用std::conditional来选择正确的类型。如果是无符号整数,选择uint,否则选择int。  typedef typename QtPrivate::QConditional<isUnsigned, uint, int>::Type Int32;  // 通过将len强制转换为Int32来选择正确的重载函数。这允许我们处理int和uint两种情况。  // we select the right overload by casting size() to int or uint // toIntegral_helper为另一个重载函数Int64 val = toIntegral_helper(data, Int32(len), ok, base);  // 检查转换后的值是否溢出。如果溢出,我们将ok设置为false,并将val设置为0。  if (T(val) != val) {  if (ok)  *ok = false;  val = 0;  }  return T(val); // 返回转换后的值。  
}

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

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

相关文章

如何使用阿里云虚拟主机和域名设置网站?

本文档将向您展示如何使用阿里云虚拟主机来设置一个新网站&#xff0c;并完成一个域名。如果您按照此处的步骤操作&#xff0c;您将启动并运行一个新网站&#xff0c;可以使用您选择的名称在全球范围内访问&#xff0c;并托管在阿里云平台上。 本文档假设您已经拥有有效的阿里…

InstructDiffusion-多种视觉任务统一框架

论文:《InstructDiffusion: A Generalist Modeling Interface for Vision Tasks》 github&#xff1a;https://github.com/cientgu/InstructDiffusion InstructPix2Pix&#xff1a;参考 文章目录 摘要引言算法视觉任务统一引导训练集重构统一框架 实验训练集关键点检测分割图像…

微信小程序本地和真机调试文件上传成功但体验版不成功

可能是微信小程序ip白名单的问题&#xff0c;去微信公众平台&#xff08;小程序&#xff09;上设置小程序的ip白名单 1、在本地中取消不校验 然后在本地去上传文件&#xff0c;就会发现控制台报错了&#xff0c;会提示一个https什么不在ip白名单&#xff0c;复制那个网址 2、…

tomcat调优配置

一. 设置账户进入管理页面 通过浏览器进入Tomcat7的管理模块页面&#xff1a;http://localhost:8080/manager/status 按照提示&#xff0c;在Tomcat7服务器指定的位置修改配置文件&#xff08;conf/tomcat-users.xml&#xff09;&#xff0c;增加相应的用户和角色配置标签 <…

win11系列:避坑宝典|win11升级最新预览体验版bug梳理

win11系列&#xff1a;避坑宝典|win11升级最新预览体验版bug梳理 一、亲测win11升级的前世今生。&#xff08;一&#xff09;问题描述梳理。&#xff08;二&#xff09;故障原因分析。&#xff08;三&#xff09;具体解决方案。2.【已解决】①尝试关Hyper-v重启&#xff1b;②从…

基于AOP的声明式事物控制

目录 Spring事务编程概述 基于xml声明式事务控制 事务属性 isolation timeout read-only propagation 全注解开发 Spring事务编程概述 事务是开发中必不可少的东西&#xff0c;使用JDBC开发时&#xff0c;我们使用connection对事务进行控制&#xff0c;使用MyBatis时&a…

Django大回顾 -3 之响应对象、cbv和fbv、关于类中self是谁的问题、上传文件、模版

【1】isinstance方法 判断一个对象是否是一个已知的类型。 isinstance语法&#xff1a; isinstance(object&#xff0c;classinfo) object --------- 实例化对象 cassinfo ------- 可以是字节或间接类名、基本类型&#xff0c;或者由他们组成的元组 相同返回True&#xff0c;不…

肖sir__mysql之视图__009

mysql之视图 一、什么是视图 视图是一个虚拟表&#xff08;逻辑表&#xff09;&#xff0c;它不在数据库中以存储形式保存&#xff08;本身包含数据&#xff09;&#xff0c;是在使用视图的时候动态生成。 二、视图作用 1、查询数据库中的非常复的数据 例如&#xff1a;多表&a…

本地部署GPT的实战方案

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

微机原理_8

一、单项选择题&#xff08;本大题共 15 小题&#xff0c;每小题 3 分&#xff0c;共 45 分。在每小题给出的四个备选项中&#xff0c;选出一个正确的答案&#xff0c;请将选定的答案填涂在答题纸的相应位置上。 1,微机内部除CPU外还集成了计算机的其它主要部件,如ROM、RAM、并…

LeetCode(38)生命游戏【矩阵】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 生命游戏 1.题目 根据 百度百科 &#xff0c; 生命游戏 &#xff0c;简称为 生命 &#xff0c;是英国数学家约翰何顿康威在 1970 年发明的细胞自动机。 给定一个包含 m n 个格子的面板&#xff0c;每一个格子都可以看成是…

shell---免交互

一、多行重定向 可以理解为这是标准输入的一种替代品&#xff0c;可以帮助脚本开发人员不必使用临时文件来构建输入信息&#xff0c;可以直接产生一个文件&#xff0c;输入文件信息&#xff0c;常与非交互程序和命令一起使用 语法格式命令<< 标记..........标记 注意…

During handling of the above exception, another exception occurred解决方案

During handling of the above exception, another exception occurred解决方案 前言解决方案总结 前言 今天在写python读取图片中的内容的脚本的时候&#xff0c;常用的图像处理库包括Pillow和OpenCV。以下是使用Pillow库读取图片中的计算公式的示例代码&#xff1a; from P…

详解原生Spring当中的额外功能开发MethodBeforeAdvice与MethodInterceptor接口!

&#x1f609;&#x1f609; 学习交流群&#xff1a; ✅✅1&#xff1a;这是孙哥suns给大家的福利&#xff01; ✨✨2&#xff1a;我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 &#x1f96d;&#x1f96d;3&#xff1a;QQ群&#xff1a;583783…

Redis对象系统

前言 在Redis中有许多数据结构&#xff0c;比如&#xff1a;简单动态字符串(SDS)&#xff0c;双端链表&#xff0c;字典&#xff0c;压缩列表&#xff0c;整数集合等。 Redis并没有直接使用这些数据结构来实现键值对数据库&#xff0c;而是基于这些数据结构创建了一个对象系统。…

vue项目运行时,报错:ValidationError: webpack Dev Server Invalid Options

在运行vue项目中&#xff0c;遇到报错&#xff1a;ValidationError: webpack Dev Server Invalid Options&#xff0c;如下图截图&#xff1a; 主要由于vue.config.js配置文件错误导致的&#xff0c;具体定位到proxy配置代理不能为空&#xff0c;导致运行项目报错&#xff0c;需…

SQL中 JOIN 的两种连接类型:内连接(自然连接、自连接、交叉连接)、外连接(左外连接、右外连接、全外连接)

SQL中 JOIN 的两种连接类型&#xff1a;内连接&#xff08;自然连接、自连接、交叉连接&#xff09;、外连接&#xff08;左外连接、右外连接、全外连接&#xff09; 1. 自然连接&#xff08;natural join&#xff09;&#xff08;内连接&#xff09; 学生表 mysql> sele…

连接备份1128

深度学习—分类识别篇&#xff1a;http://tr.daheng-imaging.com/watch/1050636http://tr.daheng-imaging.com/watch/1050636 深度学习—目标检测篇&#xff1a;http://tr.daheng-imaging.com/watch/1101141http://tr.daheng-imaging.com/watch/1101141 深度学习—缺陷分割篇&a…

Oracle研学-基础操作

学自B站黑马程序员笔记 一 创建表空间(创建数据文件) 创建表空间同时会创建一个数据文件(下面5行应该是一句话)&#xff0c;表空间在PLSQL的Object的tablespace中可以看到 create tablespace waterboss //创建表空间 datafile c:\waterboss.dbf //创建表空间对应的…

Chrome显示分享按钮

分享按钮不见了&#xff01; Chrome://flags Chrome Refresh 2023 Disabled 左上角的标签搜索会到右上角。