Qt字符串与数值相互转换

发布于:2025-08-14 ⋅ 阅读:(14) ⋅ 点赞:(0)

一、字符串转数值

在 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

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到