LINUX.ORG.RU

преобразовать строку в hexе в uint8_t вектор

 


0

1

Есть строка вида

std::string str( "001a4b0540" )

Т.е.в строке имеется хексовое представление чисел.
Ко-во символов в строке кратное 2.
Подскажите, какие существуют способы преобразовать такую строку в std::uint8_t вектор.



Последнее исправление: kabanchik (всего исправлений: 4)

Приведи пример вектора, который должен получиться из исходной строки. Тут можно по разному понять задачу, особенно если приплести little endian и big endian представления.

redbaron ★★
()
Ответ на: комментарий от redbaron

строка «01» - это число 1 строка «4b» - это число (int)0x4b[rb] и т.д.
два подряд символа в строке - это число.

kabanchik
() автор топика
Ответ на: комментарий от redbaron

Заметь: тебя никто за язык не тянул :p

asaw ★★★★★
()

Если хочется именно в стиле C++ (т.е. на кастомном итераторе с инсёртерами и алгоритмами), то могу предложить такое.

xaizek ★★★★★
()

Подскажите, какие существуют способы преобразовать такую строку в std::uint8_t вектор.

использовать std::istringstream(str) вместе с std::copy и http://en.cppreference.com/w/cpp/iterator/istream_iterator например, только нужно правильные флажки std::istringstream поставить.

asaw ★★★★★
()
Ответ на: комментарий от Stil

Так это код для одного числа (второе так не прочитается). Я не уверен, что стримы могут обрабатывать последовательности без разделителей.

xaizek ★★★★★
()
#include <iterator>
#include <vector>
#include <cstdint>
#include <string>
#include <stdexcept>

using namespace std;

int hex2int(char hexDigit)
{
    switch(hexDigit)
    {
    case '0':
    case '1':
    case '2':
    case '3':
    case '4':
    case '5':
    case '6':
    case '7':
    case '8':
    case '9':
        return ('0' - hexDigit);

    case 'a':
    case 'b':
    case 'c':
    case 'd':
    case 'e':
    case 'f':
        return (10 + 'a' - hexDigit);

    default:
        throw logical_error("Illegal hexadecimal digit");
    }
}

vector<uint8_t> hexStr2Uint8Vec(const string &str)
{
    vector<uint8_t> result;

    for(auto i = cbegin(str); i != cend(cstr); i = next(i, 2))
        result.push_back(hex2int(*i) * 16 + hex2int(*next(i)));

    return result;
}


anonymous
()

Это тут проходит конкурс на самое извращённое решение простых задач?

unsigned char conversion['g']={'0':0,'1':1,....};// всю таблицу выписывать лень
unsigned long IdontKnownAboutSscanf(unsigned char *s) {
   unsigned long ret=0;
   while(*s) {
     ret=(ret<<8)+conversion[*s++];
   }
   return ret;
}
PS. код кстати не проверял, да на С что-то давненько не писал

MKuznetsov ★★★★★
()

лехкотня же, ну

std::string str("001a4b0540");

assert(str.length());
assert(!(str.length() % 2));

std::vector<uint8_t> bytevec(str.length() / 2);

auto t = &bytevec[0];
auto f = str.c_str();

for (; *f != 0; f += 2) {
  *t++=(*f>'9'?(((*f|32)-'W')<<4):((*f-'0')<<4))|(f[1]>'9'?(f[1]|32)-'W':f[1]-'0');
}
peacelove
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.