Russian Qt Forum

Qt => Вопросы новичков => Тема начата: ADA от Июнь 29, 2011, 21:22



Название: Перевести из QString в unsigned char
Отправлено: ADA от Июнь 29, 2011, 21:22
Доброго времени суток.

Пишу простенький парсер данных, вводимых пользователем в форму. Данные считываю в переменную типа QString , далее вылавливаю нужные позиции из массива (это числа в hex коде). Далее мне необходимо побайтно засунуть их в массив и посчитать контрольную сумму.

За основу брал проект, в котором считал CRC из массива unsigned char-ов. Хотел не меняя функцию втулить туда массив байтов ( компилятор ругается все время), но почему-то на всех форумах находил конвертацию только из QString в char *.

То-ли я что-то не понимаю? Возможно ли преобразовать QString именно в unsigned char?

Тест программы выложу завтра.


Название: Re: Перевести из QString в unsigned char
Отправлено: kambala от Июнь 29, 2011, 21:26
в unsigned char можно отдельные символы преобразовывать, а никак не строку :)


Название: Re: Перевести из QString в unsigned char
Отправлено: ADA от Июнь 29, 2011, 22:17
Для примера: у меня набор данных = 0xf3,0x3d и т.д. Мне нужно проанализировать строку...выкинуть запятые, пробелы и префикс 0x естественно, а вот f3, 3d - перевести в char и совершать над ними операции, как над обычным числом.


Название: Re: Перевести из QString в unsigned char
Отправлено: kambala от Июнь 29, 2011, 22:46
если в строке запятые и пробелы расставлены случайным образом (например бывают строки вида "0х2,0х34 0х545, 0х31"), то разбиваешь строку на список чисел:
Код
C++ (Qt)
QString s;
QStringList numbers = s.split(QRegExp("[, ]+"));
(если формат точно известен, то регэкс не нужен - просто пишешь строку-разделитель), а потом проходишь по элементам списка и преобразовываешь их в числа:
Код
C++ (Qt)
foreach (QString number, numbers)
{
   bool ok;
   ushort n = number.toUShort(&ok, 16);
   if (ok)
   {
        // n - твое число
   }
}


Название: Re: Перевести из QString в unsigned char
Отправлено: ADA от Июнь 30, 2011, 09:11
Спасибо. Записал =
Код:
ushort s_rch[10];

s = ui->plainTextEdit->toPlainText();

    QStringList numbers = s.split(QRegExp("[, ]+"));

    foreach (QString number, numbers)
    {
        bool ok;
        ushort n = number.toUShort(&ok, 16);
        if (ok)
        {
           s_rch[inc] = n;// n - твое число
           inc++;
        }
    }

В s_rch - записываются нужные данные.

Теперь возникла другая проблема. CRC у меня считается через указатели (передрано с wikipedia :D) =
Код:
unsigned char crc8Res(  unsigned char *data , unsigned int len )
{
unsigned char crc = 0x00;
while( len-- )
{
crc = crc8TableA[ crc ^ *data++ ];

}
return crc;
}
Так вот проблема в том, что указатель ushort* не соответствует типу указателся unsigned char*/

Как же быть в такой ситуации?


Название: Re: Перевести из QString в unsigned char
Отправлено: LisandreL от Июнь 30, 2011, 09:24
Так вот проблема в том, что указатель ushort* не соответствует типу указателся unsigned char*
reinterpret_cast?


Название: Re: Перевести из QString в unsigned char
Отправлено: ddrtn от Июнь 30, 2011, 10:11
Не надо так делать. не поймут-с. QString - это шибко высокоуровневый инструмент. не нужно обращаться к его внутреннему представлению символов. Для этих целей существует QByteArray. Для преобразования QByteArray в QString существует много специальных функций, решающих эту задачу в зависимости от выбранной кодировки (например, QString::toLocal8Bit()).
А с QByteArray сабж решается просто:
Код:
	QByteArray ba;
const unsigned char* a = reinterpret_cast<const unsigned char*>(ba.constData());
unsigned char* b = reinterpret_cast<unsigned char*>(ba.data());


Название: Re: Перевести из QString в unsigned char
Отправлено: ADA от Июнь 30, 2011, 10:45
Я записал вот так.
Код:

unsigned char crc_out, inc, s_ch[20], inc_ch;
QString s, s_reg;
ushort s_rch[10];


unsigned char crc8Res(  unsigned char *data , unsigned int len )
{
unsigned char crc = 0x00;
while( len-- )
{
crc = crc8TableA[ crc ^ *data++ ];

}
return crc;
}

void CRC::on_pushButton_clicked()
{
   
    s = ui->plainTextEdit->toPlainText();

    QStringList numbers = s.split(QRegExp("[, ]+"));

    foreach (QString number, numbers)
    {
        bool ok;
        ushort n = number.toUShort(&ok, 16);
        if (ok)
        {
           s_rch[inc] = n;
           inc++;
        }
    }

     crc_out = crc8Res(reinterpret_cast<unsigned char*>(s_rch),inc); //Здесь пытаюсь передать переменные через указатели в функцию. Но в отладчике вижу, что предается совсем не то. Тоесть какие-то указатели предаются, но явно не на переменные с массива s_rch.

   
        ui->label->setText( QString::number(crc_out,16) );

   inc = 0;

}

Что-то у меня через cast не получилось передать нужные указатели. Ткните пальцем как надо?


Название: Re: Перевести из QString в unsigned char
Отправлено: LisandreL от Июнь 30, 2011, 10:59
Не надо так делать. не поймут-с. QString - это шибко высокоуровневый инструмент.
Вопрос был про ushort* => unsigned char*.

Что-то у меня через cast не получилось передать нужные указатели. Ткните пальцем как надо?
При беглом просмотре ошибки не вижу. Вы уверены, что передаётся не то?


Название: Re: Перевести из QString в unsigned char
Отправлено: ddrtn от Июнь 30, 2011, 11:09
Вопрос был про ushort* => unsigned char*.
Прошу прощения, не прочитал одно сообщение.


Название: Re: Перевести из QString в unsigned char
Отправлено: ADA от Июнь 30, 2011, 13:08
Что-то у меня через cast не получилось передать нужные указатели. Ткните пальцем как надо?
При беглом просмотре ошибки не вижу. Вы уверены, что передаётся не то?
Просмотрел редактором памяти. Оказалось, что указатель передается правильно, но вот данные все разделены нулевыми байтами...тоесть если в массиве s_rch они лежали так = 0х01 0x02 0x03, то по адресам указателся они лежат так = 0x01 0x00 0x02 0x00 0x03 0x00 и т.д. Это конечно исправить не трудно. Но причина , как мне кажется, в типе данных?


Название: Re: Перевести из QString в unsigned char
Отправлено: LisandreL от Июнь 30, 2011, 13:27
Ну, логично, ushort в данном случае двухбайтовый. Но это же только вы можете знать, что вам нужно.
Если этого не нужно объявите s_rch и n как quint8 или unsigned char.


Название: Re: Перевести из QString в unsigned char
Отправлено: kambala от Июнь 30, 2011, 13:41
если нужно просто посчитать контрольную сумму, то может подойдёт функция qChecksum (CRC-16)? или нужно именно по какому-то определённому алгоритму?


Название: Re: Перевести из QString в unsigned char
Отправлено: LisandreL от Июнь 30, 2011, 13:45
если нужно просто посчитать контрольную сумму, то может подойдёт функция qChecksum (CRC-16)? или нужно именно по какому-то определённому алгоритму?
Ещё есть QCryptographicHash::hash - Md4, Md5 или Sha1.


Название: Re: Перевести из QString в unsigned char
Отправлено: Igors от Июнь 30, 2011, 14:21
Так вот проблема в том, что указатель ushort* не соответствует типу указателся unsigned char*/

Как же быть в такой ситуации?
Меньше передирать :) Пытаться думать и что-то сделать самому. Если Вам обязательно нужно "crc как в Wiki", то так

Код
C++ (Qt)
unsigned char crc8Res(  const unsigned short *data, int len )
{
unsigned char crc = 0;
for (int i = 0; i < len; ++i) {
  crc = crc8TableA[crc ^ (data[i] & 0xFF) ];
  crc = crc8TableA[crc ^ ((data[i] >> 8) & 0xFF) ];
}
return crc;
}
 
А если просто/любое CRC, то хотя бы так
Код
C++ (Qt)
unsigned short MyCRC( const unsigned short *data, int len )
{
if (!len) return 0;
unsigned short crc = data[0] ^ 0xAA;
for (int i = 1; i < len; ++i)
  crc ^= data[i];
 
return crc;
}
В руках kambala все высокоуровневые штучки (RegExp. splt. foreach и.т.п.)  будут прекрасно работать :) Но когда Вы их передираете - первая "своя" строка оказывается ошибкой, напр

Код:
ushort s_rch[10];
...
    foreach (QString number, numbers)
    {
        bool ok;
        ushort n = number.toUShort(&ok, 16);
        if (ok)
        {
           s_rch[inc] = n;
           inc++;
        }
    }
А что если не "оk"? Что если inc превысило 10 (размер Вашего массива)? Если хотите продолжать "в духе Qt", то определите s_rch так
Код
C++ (Qt)
QVector <unsigned short> s_rch;
 
и избавьтесь от inc

А можно действовать и "как на С" (что мне лично нравится больше). Извлекаете из UI С строку. напр так
Код
C++ (Qt)
 QByteArray ba = ui->plainTextEdit->toPlainText().toAscii();
 const char * src = ba.constData();  
 
И работаете с этой строкой напр с помощью прекрасной ф-ции strtol, которая на порядок-два быстрее всего отого "модерна"


Название: Re: Перевести из QString в unsigned char
Отправлено: ADA от Июнь 30, 2011, 14:24
Да...там особый полином. нестандартный. Хотя в сторону готовых функция тоже погляжу. А так в общем с типами разобрался.

Всем спасибо за советы и ответы.