Qt字符串与数值相互转换
一、字符串转数值
在 Qt 框架中,字符串转数值操作主要通过 QString
类提供的转换方法实现。以下是常用方法及示例:
1. 转整数
#include <QString>
#include <QDebug>
int main() {
QString str = "42";
bool ok; // 转换状态标识
int num = str.toInt(&ok);
// 参数说明:&ok 接收转换状态(true=成功)
if(ok) {
qDebug() << "转换成功:" << num; // 输出: 42
} else {
qDebug() << "转换失败";
}
}
2. 转浮点数
QString str = "3.14159";
bool ok;
double pi = str.toDouble(&ok);
if(ok) qDebug() << pi; // 输出: 3.14159
3. 指定进制转换
支持 2~36 进制:
QString binary = "1010";
int decimal = binary.toInt(&ok, 2); // 二进制转十进制
// 结果: 10
4. 高级转换(QLocale)
处理本地化数字格式(如千分位分隔符):
#include <QLocale>
QString str = "1,024.5";
QLocale locale(QLocale::English);
double num = locale.toDouble(str, &ok);
if(ok) qDebug() << num; // 输出: 1024.5
5. 错误处理建议
- 始终检查
ok
标志位 - 处理空字符串和非法字符:
QString invalid = "12a3"; int val = invalid.toInt(&ok); // ok = false
性能提示
对高频转换场景,考虑使用 QStringView
避免内存拷贝:
QStringView view(str);
int num = view.toInt();
注意:当转换失败时,数值方法默认返回 0。建议配合 Qt 的
QVariant
实现类型安全的转换机制。
二、数值转字符串
在Qt中将数值转换为字符串有多种方法,以下是最常用的几种方式及其特点:
1、QString::number() 方法(推荐)
最简洁高效的方式,支持整数、浮点数和进制转换:
int num1 = 42;
double num2 = 3.14159;
// 整数转字符串
QString str1 = QString::number(num1); // "42"
// 浮点数转字符串(指定格式和精度)
QString str2 = QString::number(num2, 'f', 2); // "3.14"
// 'f': 固定小数格式, 2: 保留2位小数
// 进制转换(十进制转十六进制)
QString hex = QString::number(255, 16); // "ff"
2、arg() 格式化方法
适合需要嵌入变量的复杂字符串:
int age = 25;
double score = 95.5;
// 单变量
QString s1 = QString("Age: %1").arg(age); // "Age: 25"
// 多变量+精度控制
QString s2 = QString("Score: %1, Precision: %2")
.arg(score, 0, 'f', 1) // 保留1位小数
.arg(8); // "Score: 95.5, Precision: 8"
3、QLocale 本地化转换
处理本地化数字格式(如千位分隔符):
double value = 1234567.89;
QLocale locale(QLocale::German); // 德语格式
QString localized = locale.toString(value, 'f', 2);
// 输出 "1.234.567,89"(德式千位分隔)
4、 QVariant 隐式转换
适用于动态类型场景:
QVariant v1(100); // 整数
QVariant v2(2.718); // 浮点数
QString s1 = v1.toString(); // "100"
QString s2 = v2.toString(); // "2.718"
5、QTextStream 流操作
适合连续写入多个值:
int x = 10;
double y = 20.5;
QString result;
QTextStream stream(&result);
stream << "坐标: (" << x << ", " << qSetRealNumberPrecision(3) << y << ")";
// 输出 "坐标: (10, 20.500)"
性能对比
方法 | 适用场景 | 性能 |
---|---|---|
QString::number() |
简单数值转换 | ★★★★★ |
arg() |
带格式的复合字符串 | ★★★☆☆ |
QLocale |
本地化/国际化需求 | ★★★☆☆ |
QVariant |
动态类型系统 | ★★☆☆☆ |
QTextStream |
流式批量操作 | ★★★★☆ |
最佳实践建议:
- 优先使用
QString::number()
获得最佳性能- 需要格式化文本时用
arg()
- 涉及多语言支持时用
QLocale
- 避免在循环中使用
QVariant
转换(有额外开销)
三、注意事项
1、字符串到数值转换的陷阱
在Qt开发中,经常会遇到将字符串转换为数值类型的需求。然而,从包含浮点数的字符串直接转换为整型时,会出现一些不符合直觉的结果:
QString str1 = "3.14";
int val1 = str1.toInt(); // 返回0,转换失败
bool ok;
int val2 = str1.toInt(&ok); // ok为false,转换失败
正确转换方法:
QString str = "3.14";
bool ok;
double dval = str.toDouble(&ok);
if (ok) {
int ival = static_cast<int>(dval); // 3 (直接截断)
// 或者使用四舍五入
int rounded = qRound(dval); // 3 (四舍五入)
}
四、完整代码示例
#include <QCoreApplication>
#include <QString>
#include <QLocale>
#include <QDebug>
#include <cmath>
void convertNumbers() {
// 1. 直接转换会失败的情况
QString floatStr = "3.14";
qDebug() << "Direct conversion:";
qDebug() << "toInt():" << floatStr.toInt(); // 0
bool ok;
int intVal = floatStr.toInt(&ok);
qDebug() << "toInt(&ok):" << intVal << "ok?" << ok; // 0 false
// 2. 正确的两步转换法
qDebug() << "\nTwo-step conversion:";
double dval = floatStr.toDouble(&ok);
if (ok) {
int truncVal = static_cast<int>(dval); // 截断
int roundVal = qRound(dval); // 四舍五入
int floorVal = std::floor(dval); // 向下取整
int ceilVal = std::ceil(dval); // 向上取整
qDebug() << "Original:" << dval;
qDebug() << "Truncated:" << truncVal;
qDebug() << "Rounded:" << roundVal;
qDebug() << "Floored:" << floorVal;
qDebug() << "Ceiled:" << ceilVal;
} else {
qDebug() << "Invalid double value";
}
// 3. 处理本地化数字格式
qDebug() << "\nLocale-aware conversion:";
QLocale german(QLocale::German);
QString localizedStr = "3,14"; // 德语使用逗号作为小数点
dval = german.toDouble(localizedStr, &ok);
if (ok) {
qDebug() << "German 3,14 ->" << dval; // 3.14
} else {
qDebug() << "Failed to parse localized number";
}
// 4. 处理边界情况
qDebug() << "\nEdge cases:";
QString edgeCases[] = {"", " 123 ", "abc", "3.99", "-2.718", "1.5e2"};
for (const QString &str : edgeCases) {
dval = str.toDouble(&ok);
if (ok) {
int val = qRound(dval);
qDebug() << str << "->" << val;
} else {
qDebug() << str << "-> invalid number";
}
}
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
convertNumbers();
return a.exec();
}
输出:
Direct conversion:
toInt(): 0
toInt(&ok): 0 ok? false
Two-step conversion:
Original: 3.14
Truncated: 3
Rounded: 3
Floored: 3
Ceiled: 4
Locale-aware conversion:
German 3,14 -> 3.14
Edge cases:
"" -> invalid number
" 123 " -> 123
"abc" -> invalid number
"3.99" -> 4
"-2.718" -> -3
"1.5e2" -> 150