std::string和std::vector<char>有什么区别?

22

那么它们的主要区别是什么,哪些情况下会使用它们?


1
我不认为std::vector<char>有任何好的用途。 - Adrian
3
现在你看到了 https://dev59.com/rW445IYBdhLWcg3wpL1_现在您可以查看 https://dev59.com/rW445IYBdhLWcg3wpL1_ 。 - Mihran Hovsepyan
它们是不同的容器。它们可能有很多相似之处,但这就是它们的区别。尝试调用std::vector<char>对象的c_str()成员函数。 - Adrian Mole
它们在内部都是char的动态数组,但它们的接口非常不同。请查看https://en.cppreference.com/w/cpp/string/basic_string和https://en.cppreference.com/w/cpp/container/vector。 - 463035818_is_not_a_number
在实现层面上,std::string可能会使用诸如strcmp之类的函数(尽管它不一定必须这样做)。 - Adrian Mole
显示剩余2条评论
5个回答

27
  • vector<char>保证 &v[0]+n == &v[n] ,而string没有这个保证(实际上,情况是如此,但并没有保证)... 据我所知,C++0x已经给出了这个保证
  • const char*vector<char>没有隐式转换
  • string不是STL容器。例如,它没有pop_back()back()函数
  • 最后但并非最不重要的是,成员函数不同!String提供适用于字符串的函数,例如使用c_str()返回以空字符结尾的字符串

底线:当您需要操作字符串时,请使用string。当您需要一个...好吧,单个字符的向量时,请使用vector<char>...

另一个使用vector<char>的方法是避免使用vector<bool>的特化。


1
好的,谢谢@Armen。那么关于二进制数据,我可以将它保存在字符串中吗? 这个代码在所有平台上都能运行吗 str += "\01512"; - Mihran Hovsepyan
2
@Mihran:二进制怎么样了?它会将你提到的字符附加到字符串中。 - Armen Tsirunyan
1
但是它不能正确地从右操作数“\01512”生成字符串(即空字符串,因为文字以\0开头),然后将此空字符串连接到我们的“str”中,对吗? - Mihran Hovsepyan
5
有一个字符串构造函数可以接受字符串的起始和终止迭代器,并且即使在该字符串中存在嵌入的空字符,它也会遵循该长度。std::string操作还将把嵌入的空字符视为字符串的一部分。当您将该字符串传递给其他像C字符串那样使用它的对象时,问题就会出现。 - tinman
9
C++11新增了pop_back()back()等函数。 - Drealmer
显示剩余11条评论

5

std:string被用作字符串表示,并具有特定于字符串操作的方法,例如substrcompare

此外,您还可以使用c_str方法返回指向有效“C字符串”的指针,您可以将其用作仅采用const char *作为参数的函数的参数,因为它将保证返回的字符串以零终止。

std::vector<char>只是一个字符数组,最大的问题是您没有c_str方法,因此除非您始终注意在向量末尾保留0,否则无法将其作为采用const char *的函数的参数传递。


substr类似的函数也适用于向量,即std::copy - user1804599
是的,但它们不是成员函数,比如substr。我也可以使用std :: string中的std :: copy。 - bcsanches

3

std::vector<char>可以像std::string一样使用,但反过来不行。

std::vector<char>只是存储字符序列的容器,但并不是所有字符序列都是字符串。例如二进制数据应该正确地存储在std::vector<char>(或std::vector<unsigned char>)中,但将其存储在字符串中就没有意义。

在内部实现上,std::stringstd::vector<char> 可以被看作是同样的概念,但实际上有一些重要的区别:

  1. C++11引入的新要求是,std::string必须在内部存储一个以NUL结尾的字符序列。这使得它符合规范并且使与C风格字符串进行交互更容易。显然,std::vector<char>没有这样的要求,并且你不希望它有这样的要求。

  2. std::string提供了与std::vector<>非常不同且大量扩展的接口。虽然后者只是一系列无聊老旧的元素,但前者实际上被设计为表示一个字符串,因此提供了一系列与字符串相关的便利函数。(有人会认为太多了,他们更喜欢将这些功能实现为独立的“自由”函数,而不是特殊的“字符串”类的成员函数。)

  3. std::string的常见实现将使用称为“小字符串优化(SSO)”的优化,当您存储一个可以直接适合于std::string对象实例的字符串时,它避免了动态内存分配。您在std::vector<>中找不到此优化(尽管可以在自定义向量类型中实际上实现该优化)。

    为了启用小字符串优化,标准要求交换std::string会使其迭代器失效。这个要求不适用于std::vector<>

  4. 虽然现在可能只是一个历史上的好奇点(特别是因为标准库的几乎所有实现方式实际上都不是这样工作的),在C++03和先前版本的语言标准中,std::string不需要将字符串中的字符存储在连续的内存中。换句话说,它实际上并不需要被实现为围绕数组的包装器。这允许使用rope数据结构和/或写时复制策略。而std::vector<>始终需要其元素的连续存储。(C++11引入了同样的要求来要求std::string。)


1

std::string 优化了典型的字符串处理操作,例如请参考 http://www.cplusplus.com/reference/string/string/ 的最后一节 "String operations"。

std::vector 是一个通用容器,可以存储任何类型的数据,而不仅仅是字符,因此它没有特定的支持,人们通常只使用字符字符串。

旨在与字符字符串一起使用的函数通常支持 string,但不支持 vector<char>


我不是在问什么是std::string和什么是std::vector<char>。 - Mihran Hovsepyan
如果你的数据代表一段文本,请使用string,因为它专门用于此目的,并具有人们通常用于文本的操作的支持。但当然你已经知道了这一点。你的问题对我来说不够清楚。 - Szabolcs

1
你为什么要比较这些不同的数据类型?std::string 是一个库,提供了像这样简单的字符串处理功能:

std::string myString;
myString = "My Funny Text";
size_t startOfFunny = myString.find("Funny");

std::vector 没有字符串操作函数,因为它只是一种容器类型。如果您需要独立存储 char,则可以使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接