Подтвердить что ты не робот

Vector <unsigned char> vs string для двоичных данных

Какой лучший контейнер С++ для хранения двоичных данных и доступа к ним?

std::vector<unsigned char>

или

std::string

Является ли более эффективным, чем другой?
Является ли это более "правильным" использованием?

4b9b3361

Ответ 1

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

Ответ 2

Оба правильные и одинаково эффективные. Использование одного из них вместо простого массива - только для облегчения управления памятью и передачи их в качестве аргумента.

Я использую вектор, потому что намерение более ясно, чем со строкой.

Изменить: Стандарт С++ 03 не гарантирует совместимость памяти std::basic_string. Однако с практической точки зрения нет коммерческих несмежных реализаций. С++ 0x установлен в стандартизировать этот факт.

Ответ 3

Является ли более эффективным, чем другой?

Это неправильный вопрос.

Это более "правильное" использование?

Это правильный вопрос.
Это зависит. Как используются данные? Если вы собираетесь использовать данные в строке, например fashon, тогда вы должны выбрать std::string, поскольку использование std::vector может запутать последующих сопровождающих. Если, с другой стороны, большая часть манипуляций с данными выглядит как простая математика или вектор, а затем более подходит std::vector.

Ответ 4

Это комментарий к ответу dribeas. Я пишу это как ответ, чтобы иметь возможность форматировать код.

Это функция сравнения char_traits, и поведение вполне здорово:

static bool
lt(const char_type& __c1, const char_type& __c2)
{ return __c1 < __c2; }

template<typename _CharT>
int
char_traits<_CharT>::
compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
{
  for (std::size_t __i = 0; __i < __n; ++__i)
if (lt(__s1[__i], __s2[__i]))
  return -1;
else if (lt(__s2[__i], __s1[__i]))
  return 1;
  return 0;
}

Ответ 5

В течение самого долгого времени я согласился с большинством ответов здесь. Однако, только сегодня это поразило меня, почему было бы разумнее использовать std::string более std::vector<unsigned char>.

Как большинство согласен, использование одного из них будет работать отлично. Но часто время, данные файла могут быть в текстовом формате (более распространены теперь, когда XML стал основным). Это облегчает просмотр в отладчике, когда он становится уместным (и эти отладчики часто позволят вам перемещаться по байтам строки в любом случае). Но что более важно, многие существующие функции, которые можно использовать в строке, могут быть легко использованы для файлов/двоичных данных. Я обнаружил, что пишу несколько функций для обработки как строк, так и байт-массивов, и понял, насколько бессмысленно все это.

Ответ 6

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

В одном случае я предпочитал std::string более std::vector. Давайте посмотрим на подписи их конструкторов перемещения в С++ 11:

вектор (вектор & x);

string (string && str) noexcept;

В этом случае мне действительно нужен конструктор move noexcept. std::string предоставляет его, а std::vector - нет.

Ответ 7

Если вы просто хотите сохранить свои двоичные данные, вы можете использовать bitset, который оптимизирует пространство для размещения. В противном случае используйте vector, поскольку это более подходит для вашего использования.

Ответ 8

Сравните это 2 и выберите себя, что более конкретно для вас. Оба они очень надежны, работают с алгоритмами STL... Выберите себя, который более эффективен для вашей задачи.

Ответ 9

Лично я предпочитаю std::string, потому что string:: data() гораздо более интуитивно понятен для меня, когда я хочу, чтобы мой двоичный буфер вернулся в C-совместимую форму. Я знаю, что элементы вектора гарантированно хранятся, и их выполнение в коде несколько неудобно.

Это решение стиля, которое отдельный разработчик или команда должны сделать для себя.