简体   繁体   English

向量 <unsigned char> vs二进制数据的字符串

[英]vector <unsigned char> vs string for binary data

Which is a better c++ container for holding and accessing binary data? 哪个是用于保存和访问二进制数据的更好的c ++容器?

std::vector<unsigned char>

or 要么

std::string

Is one more efficient than the other? 一个比另一个更有效吗?
Is one a more 'correct' usage? 一个更“正确”的用法吗?

You should prefer std::vector over std::string . 你应该更喜欢std::vector不是std::string In common cases both solutions can be almost equivalent, but std::string s are designed specifically for strings and string manipulation and that is not your intended use. 在通常情况下,两个解决方案几乎都是等效的,但是std::string s是专为字符串和字符串操作而设计的,这不是您的预期用途。

Both are correct and equally efficient. 两者都是正确的,同样有效。 Using one of those instead of a plain array is only to ease memory management and passing them as argument. 使用其中一个而不是普通数组只是为了简化内存管理并将它们作为参数传递。

I use vector because the intention is more clear than with string. 我使用vector是因为意图比使用string更清晰。

Edit: C++03 standard does not guarantee std::basic_string memory contiguity. 编辑: C ++ 03标准不保证std::basic_string内存连续性。 However from a practical viewpoint, there are no commercial non-contiguous implementations. 然而,从实践的角度来看,没有商业非连续的实现。 C++0x is set to standardize that fact . C ++ 0x设置为标准化该事实

Is one more efficient than the other? 一个比另一个更有效吗?

This is the wrong question. 这是一个错误的问题。

Is one a more 'correct' usage? 一个更“正确”的用法吗?

This is the correct question. 这是正确的问题。
It depends. 这取决于。 How is the data being used? 如何使用数据? If you are going to use the data in a string like fashon then you should opt for std::string as using a std::vector may confuse subsequent maintainers. 如果您要使用像fashon这样的字符串中的数据,那么您应该选择std :: string,因为使用std :: vector可能会混淆后续的维护者。 If on the other hand most of the data manipulation looks like plain maths or vector like then a std::vector is more appropriate. 另一方面,如果大多数数据操作看起来像普通数学或矢量,那么std :: vector更合适。

This is a comment to dribeas answer. 这是对运动答案的评论。 I write it as an answer to be able to format the code. 我把它写成一个能够格式化代码的答案。

This is the char_traits compare function, and the behaviour is quite healthy: 这是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;
}

For the longest time I agreed with most answers here. 最长的时间我在这里同意了大多数答案。 However, just today it hit me why it might be more wise to actually use std::string over std::vector<unsigned char> . 然而,就在今天,它让我觉得为什么在std::vector<unsigned char>上实际使用std::string可能更明智。

As most agree, using either one will work just fine. 大多数人都同意,使用其中任何一个都可以正常工作。 But often times, file data can actually be in text format (more common now with XML having become mainstream). 但通常情况下,文件数据实际上可以是文本格式(现在更常见的是XML已成为主流)。 This makes it easy to view in the debugger when it becomes pertinent (and these debuggers will often let you navigate the bytes of the string anyway). 这使得在调试器变得相关时可以很容易地在调试器中查看(并且这些调试器通常会让您无论如何都可以导航字符串的字节)。 But more importantly, many existing functions that can be used on a string, could easily be used on file/binary data. 但更重要的是,许多可用于字符串的现有函数可以很容易地用于文件/二进制数据。 I've found myself writing multiple functions to handle both strings and byte arrays, and realized how pointless it all was. 我发现自己编写了多个函数来处理字符串和字节数组,并意识到这一切都是毫无意义的。

As far as readability is concerned, I prefer std::vector. 就可读性而言,我更喜欢std :: vector。 std::vector should be the default container in this case: the intent is clearer and as was already said by other answers, on most implementations, it is also more efficient. 在这种情况下,std :: vector应该是默认容器:意图更清晰,正如其他答案已经说过的那样,在大多数实现中,它也更有效。

On one occasion I did prefer std::string over std::vector though. 有一次,我确实更喜欢std :: string而不是std :: vector。 Let's look at the signatures of their move constructors in C++11: 让我们看一下C ++ 11中移动构造函数的签名:

vector (vector&& x); vector(vector && x);

string (string&& str) noexcept ; string(string && str) noexcept ;

On that occasion I really needed a noexcept move constructor. 那次我真的需要一个noexcept移动构造函数。 std::string provides it and std::vector does not. std :: string提供它而std :: vector不提供它。

If you just want to store your binary data, you can use bitset which optimizes for space allocation. 如果您只想存储二进制数据,可以使用优化空间分配的bitset Otherwise go for vector , as it's more appropriate for your usage. 否则请使用vector ,因为它更适合您的使用。

Compare this 2 and choose yourself which is more specific for you. 比较这2并选择你自己哪个更具体。 Both are very robust, working with STL algorithms ... Choose yourself wich is more effective for your task 两者都非常强大,使用STL算法...选择自己对您的任务更有效

Personally I prefer std::string because string::data() is much more intuitive for me when I want my binary buffer back in C-compatible form. 我个人更喜欢std :: string,因为当我希望我的二进制缓冲区恢复为C兼容形式时,string :: data()对我来说更直观。 I know that vector elements are guaranteed to be stored contiguously exercising this in code feels a little bit unsettling. 我知道向量元素保证连续存储在代码中执行此操作感觉有点令人不安。

This is a style decision that individual developer or a team should make for themselves. 这是个人开发人员或团队应该为自己做出的风格决策。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM