vector <unsigned char> против строки для двоичных данных - PullRequest
23 голосов
/ 12 октября 2009

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

std::vector<unsigned char>

или

std::string

Один эффективнее другого?
Является ли один из них более «правильным»?

Ответы [ 9 ]

26 голосов
/ 13 октября 2009

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

13 голосов
/ 12 октября 2009

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

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

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

4 голосов
/ 12 октября 2009

Один эффективнее другого?

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

Является ли один из них более «правильным»?

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

1 голос
/ 28 ноября 2017

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

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

1 голос
/ 13 октября 2009

Это комментарий к ответу 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;
}
0 голосов
/ 24 июня 2014

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

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

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

строка (строка && str) без исключения ;

В тот раз мне действительно был нужен конструктор перемещения noexcept. std :: string предоставляет, а std :: vector - нет.

0 голосов
/ 13 октября 2009

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

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

0 голосов
/ 12 октября 2009

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

0 голосов
/ 12 октября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...