Converting a QString with a binary into a QString with a hex - c++

I am wondering what the most efficient way would be to convert a binary that is saved as a QString into the corresponding Hex and save it in the same QString
QString value = "10111100"
into
value = "bc"

It's simple. First convert your binary string to an integer:
QString value = "10111100";
bool fOK;
int iValue = value.toInt(&fOk, 2); //2 is the base
Then convert the integer to hex string:
value = QString::number(iValue, 16); //The new base is 16

Related

How to convert a QString containing a hex value to an uint?

QString samp_buff[100];
QByteArray data;
uint8_t speed;
samp_buff[3] = data.toHex(); //I converted the QByteArray into a string
qDebug() << "read_every_data_"<< samp_buff[3];
speed = samp_buff[3].toUInt(); //Trying to convert the string to uint8_t
qDebug() << "Converted to UINT8" << speed;
Hi! I successfully got the Qbytearray value (data) stored in as a QString in the samp_buff array of strings, and also during the conversion of QString to uint8_t in the form of hex.
Data: "\x07" //QByteArray
read_every_data_ "07" //QString
Converted to UINT8 7 //Uint8_t
Its working fine for this but the problem arises when this happens.
Data: "\x0B" //QByteArray
read_every_data_ "0b" //QString
Converted to UINT8 0 //Uint8_t
Whenever the hex string has alphabets in it, the result of the conversion becomes zero.
As the documentation of QString::toUint suggests, the signature of the function looks like this.
uint QString::toUInt(bool *ok = nullptr, int base = 10) const
The second argument base is for specifying the base. To convert from hex strings, supply 16 to it.
speed = samp_buff[3].toUInt(nullptr, 16);

error: no viable conversion from 'std::__1::basic_string<char>' to 'const QString' [duplicate]

What is the most basic way to do it?
If compiled with STL compatibility, QString has a static method to convert a std::string to a QString:
std::string str = "abc";
QString qstr = QString::fromStdString(str);
If by string you mean std::string you can do it with this method:
QString QString::fromStdString(const std::string & str)
std::string str = "Hello world";
QString qstr = QString::fromStdString(str);
If by string you mean Ascii encoded const char * then you can use this method:
QString QString::fromAscii(const char * str, int size = -1)
const char* str = "Hello world";
QString qstr = QString::fromAscii(str);
If you have const char * encoded with system encoding that can be read with QTextCodec::codecForLocale() then you should use this method:
QString QString::fromLocal8Bit(const char * str, int size = -1)
const char* str = "zażółć gęślą jaźń"; // latin2 source file and system encoding
QString qstr = QString::fromLocal8Bit(str);
If you have const char * that's UTF8 encoded then you'll need to use this method:
QString QString::fromUtf8(const char * str, int size = -1)
const char* str = read_raw("hello.txt"); // assuming hello.txt is UTF8 encoded, and read_raw() reads bytes from file into memory and returns pointer to the first byte as const char*
QString qstr = QString::fromUtf8(str);
There's also method for const ushort * containing UTF16 encoded string:
QString QString::fromUtf16(const ushort * unicode, int size = -1)
const ushort* str = read_raw("hello.txt"); // assuming hello.txt is UTF16 encoded, and read_raw() reads bytes from file into memory and returns pointer to the first byte as const ushort*
QString qstr = QString::fromUtf16(str);
Alternative way:
std::string s = "This is an STL string";
QString qs = QString::fromAscii(s.data(), s.size());
This has the advantage of not using .c_str() which might cause the std::string to copy itself in case there is no place to add the '\0' at the end.
std::string s = "Sambuca";
QString q = s.c_str();
Warning: This won't work if the std::string contains \0s.
I came across this question because I had a problem when following the answers, so I post my solution here.
The above examples all show samples with strings containing only ASCII values, in which case everything works fine. However, when dealing with strings in Windows whcih can also contain other characters, like german umlauts, then these solutions don't work
The only code that gives correct results in such cases is
std::string s = "Übernahme";
QString q = QString::fromLocal8Bit(s.c_str());
If you don't have to deal with such strings, then the above answers will work fine.
Do you mean a C string, as in a char* string, or a C++ std::string object?
Either way, you use the same constructor, as documented in the QT reference:
Qt QString Reference
For a regular C string, just use the main constructor:
char name[] = "Stack Overflow";
QString qname(name);
For a std::string, you obtain the char* to the buffer and pass that to the QString constructor:
std::string name2("Stack Overflow");
QString qname2(name2.c_str());
Moreover, to convert whatever you want, you can use the QVariant class.
for example:
std::string str("hello !");
qDebug() << QVariant(str.c_str()).toString();
int test = 10;
double titi = 5.42;
qDebug() << QVariant(test).toString();
qDebug() << QVariant(titi).toString();
qDebug() << QVariant(titi).toInt();
output
"hello !"
"10"
"5.42"
5

Qt converting string to int in base 16 but remain the value of base 16

This have been troubled me for days and I really have no clue so to trouble Y'all.
I have an input in Qt to get any number from the user input.
After the user input the number, I get the number and convert it into hexadecimal (base 16) after I convert it, if the hexadecimal is more than 1 bytes, I will split it into 1 bytes size. I have done all the conversion and splitting.
Now my problem is , after I convert and split, the hexadecimal stays in the data type of QString, but in order to sent inside the QBtyeArray, I need convert back to int.
Can you guys tell me is there any convenient way to convert QString back to the int? I have tried a lot of ways but all of the conversion give me the value of base 10, I want the value to be in base 16 but in int.
Example : The user input 10800 (base 10) in the lineEdit , I retrieve the 10800 from lineEdit and after that I convert it to a base 16, so the hexadecimal of 10800 is 2A30 , after I do the conversion , the value 2A30 is in string , may I know how to convert the type into int but the value still stays as 2A30 but not convert back to 10800 (base 10).
The closest answer I get is through this method
unsigned int value = QString("0x2A").toUInt(&ok, 16);
int abcde = sprintf(abc, "%x", value);
qDebug()<<QString::number(value);
QByteArray test_a = abc;
but either it returns me QByteArray or char, I want it in int, because I need to specify each bytes I send in writeDatagram() functions like this.
QByteArray datagram(4, '\x000');
datagram[0] = 0x02;
datagram[1] = 0x10;
datagram[2] = 0x00;
datagram[3] = 0x00;
Please tell me if my question is not clear enough. I'm using Qt 5.2.1
Thanks !!!
Why do you do the conversion etc.? I presume that you want to send an arbitrarily long integers in, effectively, base 256, i.e. one byte and at a time, instead of, say one decimal digit at a time. I also assume you want to represent them big endian, i.e. the most significant base-256 digit comes first. Say if you had to send 12384928, it'd be sent as bytes 188, 250, 160 (0xbc, 0xfa, 0xa0).
That's pretty easy to do:
QByteArray numberToBytes(const QString &number) {
QByteArray result;
bool ok = false;
auto value = number.toLongLong(&ok);
if (ok) {
int n = sizeof(value);
while (value && n--) {
result.append(quint8(value & 0xFF));
value = value >> 8;
}
std::reverse(result.begin(), result.end());
}
return result;
}
QString bytesToNumber(const QByteArray &bytes) {
qlonglong value = 0;
for (auto b : bytes)
value = (value << 8) | quint8(b);
return QString::number(value);
}
void test() {
Q_ASSERT(sizeof(qlonglong) == 8);
Q_ASSERT(numberToBytes("256") == QByteArray::fromRawData("\x01\x00", 2));
Q_ASSERT(numberToBytes("2134789") == QByteArray::fromRawData("\x20\x93 \x05", 3));
Q_ASSERT(numberToBytes("-58931") == QByteArray::fromRawData("\xFF\xFF\xFF\xFF\xFF\xFF\x19\xCD");
}
You might also consider numbers too long to fit in 8 bytes. Those require a slightly more involved radix change operation - after all, you don't really want to be doing repetitive long divisions. See this page for details.
But it really looks as if you want to simply send strings in datagrams. If you wish to append a checksum (here: CCITT CRC-16) to the data, that's not hard either, because Qt does it for us:
QByteArray serialize(const QString &str, bool withCRC = false) {
QByteArray result;
QDataStream ds(&result, QIODevice::WriteOnly);
ds << str;
if (withCRC) ds << qChecksum(result.constData(), result.size());
return result;
}
QString deserialize(const QByteArray &packet, bool withCRC = false) {
QString result;
QDataStream ds(packet);
ds >> result;
if (withCRC) {
quint16 crc;
ds >> crc;
crc ^= qChecksum(packet.data(), packet.size() - 2);
if (crc) return {};
}
return result;
}
The format of the datagram is as follows: length of the string (4 bytes), followed by each character in the string (2 bytes each - it's a QChar). The optional CRC is another 2 bytes. That's all there's to that.
If the string has only ASCII characters, then sending the UTF-8 representation will take half the space if the string is long:
QByteArray serialize(const QString &str, bool withCRC = false) {
QByteArray result;
QDataStream ds(&result, QIODevice::WriteOnly);
ds << str.toUtf8();
if (withCRC) ds << qChecksum(result.constData(), result.size());
return result;
}
QString deserialize(const QByteArray &packet, bool withCRC = false) {
QByteArray result;
QDataStream ds(packet);
ds >> result;
if (withCRC) {
quint16 crc;
ds >> crc;
crc ^= qChecksum(result.constData(), result.size());
if (crc) return {};
}
return QString::fromUtf8(result);
}
Perhaps you tried to make the string smaller by knowing ahead of time that it is a number, and thus representing it optimally. How long do you expect those strings to be, and what is your limit on the datagram size?

Convert QString hexadecimal to ASCII value

My goal is to convert an hexadecimal value which is contained in a QString to its ASCII value.
I have :
QString hexaValue = receiveText.left(14); // receive texte is another QString
My problem here, is that I have my hexadecimal value in a Qstring and not in a QByteArray, so all of the solutions that I found are not working, I try to call .data() or fromHex() , but this ain't working here, because I'm forced to used a QString and not a QByteArray
Should I convert my QString to a QByteArray, is there a simple solution ?
You can just use QString::toLatin1to convert hex string to QByteArray and to convert it back to QString use either QString::fromLocal8Bit for local encoding or QString::fromUtf8 if your hex encoded string are in UTF8.
QString hexaValue = receiveText.left(14); // received text is another QString
QString textValue = QString::fromLocal8Bit(QByteArray::fromHex(hexaValue.toLatin1()));

Convert QString to Hex?

I have a QString where I append data input from the user.
At the end of the QString, I need to append the hexadecimal representation of a "Normal" QString.
For example:
QString Test("ff00112233440a0a");
QString Input("Words");
Test.append(Input);//but here is where Input needs to be the Hex representation of "Words"
//The resulting variable should be
//Test == "ff00112233440a0a576f726473";
How can I convert from ASCII (I think) to it's Hex representation?
Thanks for your time.
You were very close:
Test.append(QString::fromLatin1(Input.toLatin1().toHex()));
Another solution to your problem.
Given a character, you can use the following simple function to compute its hex representation.
// Call this function twice -- once with the first 4 bits and once for the last
// 4 bits of a char to get the hex representation of a char.
char toHex(char c) {
// Assume that the input is going to be 0-F.
if ( c <= 9 ) {
return c + '0';
} else {
return c + 'A' - 10;
}
}
You can use it as:
char c;
// ... Assign a value to c
// Get the hex characters for c
char h1 = toHex(c >> 4);
char h2 = toHex(c & 0xF);