Есть ли простой способ использования класса QVariant с шестнадцатеричными строками? - PullRequest
1 голос
/ 09 февраля 2012

Этот пример кода работает так, как я ожидал:

v = QVariant("123456");
qDebug() << v; // QVariant(QString, "123456")
v.convert(QVariant::Int);
qDebug() << v; // QVariant(int, 123456)
v.convert(QVariant::String);
qDebug() << v; // QVariant(QString, "123456")

Где это не так:

v = QVariant("0xBEEF");
qDebug() << v; // QVariant(QString, "0xBEEF")
v.convert(QVariant::Int);
qDebug() << v; // QVariant(int, 0)
v.convert(QVariant::String);
qDebug() << v; // QVariant(QString, "")

Есть ли простой способ заставить класс QVariant работать с шестнадцатеричными строками, чтобы второй пример работал примерно так:

v = QVariant("0xBEEF");
qDebug() << v; // QVariant(QString, "0xBEEF")
v.convert(QVariant::Int);
qDebug() << v; // QVariant(int, 48879)
v.convert(QVariant::String);
qDebug() << v; // QVariant(QString, "48879")

Ответы [ 2 ]

2 голосов
/ 09 февраля 2012

При преобразовании qvariant в числовое значение необходимо указать основание. Также убедитесь, что значение будет соответствовать int / long / longlong, иначе преобразование по этой причине завершится неудачно.

QVariant v = QVariant("0xDEADBEAF");
bool test;
qDebug() << v.toString().toLongLong(&test,16);
qDebug() << test;

выдаст правильный вывод

3735928495 
true 

пока

QVariant v = QVariant("0xDEADBEAF");
bool test;
qDebug() << v.toString().toInt(&test,16);
qDebug() << test;

выдаст

0
false
1 голос
/ 09 февраля 2012

После замечаний, сделанных этим ответом о численном переполнении, я провел некоторое исследование, и кажется, что процедуры преобразования QVariant ошибочны.Самый простой способ безопасно конвертировать QVariant - использовать вместо этого преобразования QString.Это также кажется самым простым способом использования QVariant с шестнадцатеричными строками.Я резюмировал свои выводы ниже.Комментарии были бы результатом вывода вызова qDebug() << v; в этой точке кода.

Сценарий 1: число, хранящееся в шестнадцатеричной строке

v = QVariant("0xBEEF"); // 'QVariant(QString, "0xBEEF") '
v = v.toString().toInt(0, 16); // 'QVariant(int, 48879) '

v = QVariant("0xDEADBEEF"); // 'QVariant(QString, "0xDEADBEEF") '
v = v.toString().toInt(0, 16); // 'QVariant(int, 0) '

Самый простой и безопасныйспособ преобразования строки, представляющей десятичное число, в тип числа с помощью метода toInt(bool * ok = 0, int base = 10) QString.

Сценарий 2: Число, хранящееся в виде десятичной строки

v = QVariant("123456"); // 'QVariant(QString, "123456") '
v.convert(QVariant::Int); // 'QVariant(int, 123456) '

Метод convert(Type t) QVariant работает так, как и следовало ожидать в этом сценарии.

v = QVariant("2147483649"); // 'QVariant(QString, "2147483649") '
v.convert(QVariant::Int); // 'QVariant(int, -2147483647) '

v = QVariant("9223372036854775807"); // 'QVariant(QString, "9223372036854775807") '
v.convert(QVariant::Int); // 'QVariant(int, -1) '

Однако использование того же метода, когда строка содержит число, которое слишком велико для типа данных, приводит к тихому переполнениюсделать что-то более полезное, например, вернуть false и установить QVariant в 0.

v = QVariant("2147483649"); // 'QVariant(QString, "2147483649") '
v = v.toString().toInt(); // 'QVariant(int, 0) '

v = QVariant("9223372036854775807"); // 'QVariant(QString, "9223372036854775807") '
v = v.toString().toInt(); // 'QVariant(int, 0) '

Используя тот же метод, что и в сценарии 1, можно предотвратить это, а также использовать необязательный параметр *booltoInt() для оповещения о сбоях.

...