Russian Qt Forum
Май 08, 2024, 23:24 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Перевести из QString в unsigned char  (Прочитано 13361 раз)
ADA
Гость
« : Июнь 29, 2011, 21:22 »

Доброго времени суток.

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

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

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

Тест программы выложу завтра.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #1 : Июнь 29, 2011, 21:26 »

в unsigned char можно отдельные символы преобразовывать, а никак не строку Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
ADA
Гость
« Ответ #2 : Июнь 29, 2011, 22:17 »

Для примера: у меня набор данных = 0xf3,0x3d и т.д. Мне нужно проанализировать строку...выкинуть запятые, пробелы и префикс 0x естественно, а вот f3, 3d - перевести в char и совершать над ними операции, как над обычным числом.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #3 : Июнь 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 - твое число
   }
}
« Последнее редактирование: Июнь 29, 2011, 22:48 от kambala » Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
ADA
Гость
« Ответ #4 : Июнь 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 Веселый) =
Код:
unsigned char crc8Res(  unsigned char *data , unsigned int len )
{
unsigned char crc = 0x00;
while( len-- )
{
crc = crc8TableA[ crc ^ *data++ ];

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

Как же быть в такой ситуации?
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #5 : Июнь 30, 2011, 09:24 »

Так вот проблема в том, что указатель ushort* не соответствует типу указателся unsigned char*
reinterpret_cast?
Записан
ddrtn
Гость
« Ответ #6 : Июнь 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());
Записан
ADA
Гость
« Ответ #7 : Июнь 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 не получилось передать нужные указатели. Ткните пальцем как надо?
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #8 : Июнь 30, 2011, 10:59 »

Не надо так делать. не поймут-с. QString - это шибко высокоуровневый инструмент.
Вопрос был про ushort* => unsigned char*.

Что-то у меня через cast не получилось передать нужные указатели. Ткните пальцем как надо?
При беглом просмотре ошибки не вижу. Вы уверены, что передаётся не то?
Записан
ddrtn
Гость
« Ответ #9 : Июнь 30, 2011, 11:09 »

Вопрос был про ushort* => unsigned char*.
Прошу прощения, не прочитал одно сообщение.
Записан
ADA
Гость
« Ответ #10 : Июнь 30, 2011, 13:08 »

Что-то у меня через cast не получилось передать нужные указатели. Ткните пальцем как надо?
При беглом просмотре ошибки не вижу. Вы уверены, что передаётся не то?
Просмотрел редактором памяти. Оказалось, что указатель передается правильно, но вот данные все разделены нулевыми байтами...тоесть если в массиве s_rch они лежали так = 0х01 0x02 0x03, то по адресам указателся они лежат так = 0x01 0x00 0x02 0x00 0x03 0x00 и т.д. Это конечно исправить не трудно. Но причина , как мне кажется, в типе данных?
Записан
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #11 : Июнь 30, 2011, 13:27 »

Ну, логично, ushort в данном случае двухбайтовый. Но это же только вы можете знать, что вам нужно.
Если этого не нужно объявите s_rch и n как quint8 или unsigned char.
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4727



Просмотр профиля WWW
« Ответ #12 : Июнь 30, 2011, 13:41 »

если нужно просто посчитать контрольную сумму, то может подойдёт функция qChecksum (CRC-16)? или нужно именно по какому-то определённому алгоритму?
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
LisandreL
Птица говорун
*****
Offline Offline

Сообщений: 984


Надо улыбаться


Просмотр профиля
« Ответ #13 : Июнь 30, 2011, 13:45 »

если нужно просто посчитать контрольную сумму, то может подойдёт функция qChecksum (CRC-16)? или нужно именно по какому-то определённому алгоритму?
Ещё есть QCryptographicHash::hash - Md4, Md5 или Sha1.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #14 : Июнь 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, которая на порядок-два быстрее всего отого "модерна"
« Последнее редактирование: Июнь 30, 2011, 14:24 от Igors » Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.161 секунд. Запросов: 22.