Обратный порядок шестнадцатеричного std :: string

0

Я работаю со старой программой и нуждаюсь в помощи, заменяющей порядок Hex String.

Да, строка... как в:

string hexString = "F07D0079"
string hexString2= "F07F"

Мне нужно, чтобы каждая строка выглядела так: 79007DF0 и 7FF0 соответственно.

Для любви к Богу я не знаю, почему они хранятся в строках, но они есть.
Это небольшая проблема с endian/big endian, но поскольку она в строке я не могу использовать стандартные функции для изменения порядка, могу ли я?

Есть ли простой способ сделать это?

std::string swapValues(string originalHex)
{
  string swappedHex;
  //what to do here.
  return swappedHex;
}
  • 1
    Как будто не было никаких функций stdlib, работающих со строками ...
  • 0
    "но так как это в строке, я не могу использовать стандартные функции, чтобы изменить порядок, могу я?" Э-э ... почему это может быть проблемой? Stl работает с stl-контейнерами, а string является таким контейнером.
Теги:

4 ответа

2
Лучший ответ

Я могу использовать функцию-член append.

std::string reverse_pairs(std::string const & src)
{
    assert(src.size() % 2 == 0);
    std::string result;
    result.reserve(src.size());

    for (std::size_t i = src.size(); i != 0; i -= 2)
    {
        result.append(src, i - 2, 2);
    }

    return result;
}

(В качестве упражнения в расширяемости вы также можете сделать параметр " 2 ").

Если вы хотите сделать это на месте, вы можете использовать std::rotate в цикле.

4

Сначала проверьте, что длина четная (если она еще не была дезинфицирована):

assert(hex.length() % 2 == 0);

Затем измените строку:

std::reverse(hex.begin(), hex.end());

Теперь байты находятся в правильном порядке, но цифры внутри каждого из них ошибочны, поэтому нам нужно их поменять:

for (auto it = hex.begin(); it != hex.end(); it += 2) {
    std::swap(it[0], it[1]);
}
  • 0
    Разве его не используют it[0] вызывает проблемы? Кто говорит, что существует? Почему std::iter_swap вместо этого не использовать std::iter_swap ?
  • 1
    @KerrekSB: Стандарт говорит, что он существует (для итераторов с произвольным доступом) и эквивалентен *(it+0) . Вы можете использовать iter_swap или другие альтернативы, если это не подходит для вашей эстетики.
Показать ещё 1 комментарий
1

Я бы не стал беспокоиться о чем-то слишком умном для этого:

std::string swapValues(const std::string& o)
{
    std::string s(o.length());

    if (s.length() == 4) {
        s[0] = o[2];
        s[1] = o[3];
        s[2] = o[0];
        s[3] = o[1];
      return s;
    }
    if (s.length() == 8) {
        // left as an exercise
    }

    throw std::logic_error("You got to be kidding me...");
}
0

Должны быть доступны библиотечные функции (наивное манипулирование строками может быть бесполезным):

#include <iostream>
#include <arpa/inet.h>

int main() {
    std::string hex32 = "F07D0079";
    std::string hex16 = "F07F";
    std::uint32_t u32 = std::strtoul(hex32.c_str(), 0, 16);
    std::uint16_t u16 = std::strtoul(hex16.c_str(), 0, 16);
    // Here we would need to know the endian of the sources.
    u32 = ntohl(u32);
    u16 = ntohs(u16);
    std::cout << std::hex << u32 << ", " << u16 << '\n';
}

Linux/Little Endian

Любая функция, действующая на строки, должна знать целевую платформу (следовательно, нет общего решения)

  • 0
    Это работает, только если ntohl и ntohs являются частью вашей библиотеки компилятора.
  • 0
    @ThomasMatthews Конечно, но это все равно зависит от платформы / машины

Ещё вопросы

Сообщество Overcoder
Наверх
Меню