0

I have a QString of 1500 QChar which I want to convert to an array of uint32_t. I am reading each element in for loop and trying to save each QChar of QString to uint32_t array. I can convert it to its equivalent representation (e.g. 1 -> 49) through data[i].unicode() but I want the same string in an uint32_t array form for further processing.

QString data = {1,'A','C',9,8,.....};
uint32_t Test[data.length()] = {0};
for (uint32_t i =0; i<data.length(); i++) {
    Test[i] = data[i]; // here i need QChar to uint32_t conversion
}

Any solutions?

m7913d
  • 10,244
  • 7
  • 28
  • 56
aly
  • 17
  • 5
  • Isn't `uint16_t` much suitable data type for such conversion? Note, that `QChar` represents 16 bits. – vahancho May 24 '17 at 11:36
  • What do you want saved in the uint32? As UTF8, UTF16 or UTF32? Also, quoting the QT website: "The QChar class provides a 16-bit Unicode character." – RvdK May 24 '17 at 11:37
  • I want to save it as uint32_t. After conversion I will pass this to another function that accepts an array of uint32_t type only. A Qstring of 8 QChars can be converted to uint32_t type using `data.toUInt(nullptr,16)` but as I have a very long string I need to do each individual item seprately. – aly May 24 '17 at 11:48
  • 1
    Please edit the question to describe what you mean by the word *convert*. That word is almost meaningless by itself. `string.toUInt(...)` is a means to convert a textual representation of a number into an integer, e.g. `Q_ASSERT(QStringLiteral("789ABC").toUint({},16) == 0x789ABC)`. At the very minimum, please provide some conversion examples stated as assertions on some `convert` function that you seek that you intend to hold. That's a good way of specifying what you expect said `convert` function to do. – Kuba hasn't forgotten Monica May 24 '17 at 12:18
  • I want to store items of `QString data` in `uint32_t Test[]` array. E.g. If I have `QString data = {1,'A','C',9,8,.....}` as input than at output I want to have `uint32_t Test = {1,'A','C',9,8,.....}`. – aly May 24 '17 at 12:41
  • Does your code compile? What is the output you obtain with your current code? – m7913d May 24 '17 at 12:50
  • @aly Please edit the question to make it complete and then delete the comments. – Kuba hasn't forgotten Monica May 24 '17 at 13:35

2 Answers2

0

Taking into account that each QChar holds only 16 bits and consist of two parts: cell and row, you can even pack two QChars into a single uint32_t number. I would do it in the following way:

QString data("ABCDE");
std::vector<uint32_t> test((data.count() + 1) / 2, 0);

for (int i = 0; i < data.length(); ++i)
{
    const QChar &c = data[i];
    uchar cell = c.cell();
    uchar row = c.row();

    uint32_t &ui32 = test[i / 2];
    if (i % 2 == 0)
    {
        ui32 = cell;
    }
    else
    {
        ui32 <<= 8;
        ui32 |= cell;
    }
    ui32 <<= 8;
    ui32 |= row;
}

However if you still need to have a single integer number per QChar you can write similar loop without compression like:

QString data("ABCDE");    
std::vector<uint32_t> test(data.count(), 0);

for (int i = 0; i < data.length(); ++i)
{
    const QChar &c = data[i];
    uchar cell = c.cell();
    uchar row = c.row();

    uint32_t &ui32 = test[i];
    ui32 = cell;
    ui32 <<= 8;
    ui32 |= row;
}
vahancho
  • 20,808
  • 3
  • 47
  • 55
0

I want to store items of QString data in uint32_t Test[] array. E.g. If I have QString data = {1,'A','C',9,8,.....} as input than at output I want to have uint32_t Test = {1,'A','C',9,8,.....}

It's not complicated at all. Each QChar is a thin wrapper around uint16_t. All you need to do is to convert those to uint32_t and you're done.

QVector<uint32_t> convert(const QString & str) {
  QVector<uint32_t> output;
  output.reserve(str.size());
  for (auto c : str)
    output.append(c.unicode());
  return output;
}

void user(const uint32_t *, size_t size);

void test(const QString & str) {
  auto const data = convert(str);
  user(data.data(), size_t(data.size());
}

Of course it might be that you have wrong assumptions about the meaning of uint32_t. The code above assumes that the user expects UTF16 code units. It's more likely, though, that user expects UTF32 code units, i.e. each uint32_t represents exactly one Unicode code point.

In the latter case, you have to convert conjugate pairs of UTF16 code units to single UTF32 code units:

QVector<uint32_t> convert(const QString & str) {
  return str.toUcs4();
}

Note that code point and code unit have specific meanings and are not synonymous.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313