Remove ads
来自维基百科,自由的百科全书
<string>是C++标准程序库中的一个头文件,定义了C++标准中的字符串的基本模板类std::basic_string及相关的模板类实例:
模板类实例 | std::basic_string的模板实参 |
---|---|
string |
char
|
wstring |
wchar_t
|
u16string |
char16_t (C++11新增)
|
u32string |
char32_t (C++11新增)
|
其中的string是以char作为模板参数的模板类实例[1],把字符串的内存管理责任由string
负责而不是由编程者负责,大大减轻了C语言风格的字符串的麻烦。
std::basic_string
提供了大量的字符串操作函数,如比较、连接、搜索、替换、获得子串等。并可与C语言风格字符串双向转换。std::basic_string
属于C++ STL容器类,用户自定义的类也可以作为它的模板参数,因此也适用C++ STL Algorithm库。
string
本质上是以字符作为元素的vector特化版本;不存在0字符结尾这个概念,能装入'\0'这种数据。
std::basic_string
类模板存储且操纵类似char的对象的序列。该对象类型的性质由特性类模板std::char_traits的实例来提供,并作为std::basic_string
的第二个模板参数。
C++11标准规定:basic_string的元素是连续存储的。即对于basic_string s,有:&*(s.begin() + n) == &*s.begin() + n
,其中n属于[0, s.size())。换句话说,指向s[0]的指针即为指向CharT[]数组的首元素指针。C++11已经禁止了写入时复制(copy-on-write)的实现,因为存在多线程安全问题。一般都采用了小字符串优化(SSO)实现,如Visual C++:
union _Bxty
{ // storage for small buffer or pointer to larger one
_Elem _Buf[_BUF_SIZE];
_Elem *_Ptr;
} _Bx;
size_type _Mysize; // current length of string
size_type _Myres; // current storage reserved for string
GCC从版本5开始,std::string不再采用COW策略。
C++17标准规定,basic_string是AllocatorAwareContainer, SequenceContainer与ContiguousContainer。
下面列出所有成员函数,其中 string
是 std::basic_string<T>
的简写:
string::string
(构造)string::~string
(析构)string::operator=
- 赋值string::assign
–赋值string::get_allocator
–获得内存分配器string::clear
–清空内容string::insert
–插入字符或字符串。目标 string 中的插入位置可用整数值或迭代器表示。如果参数仅为一个迭代器,则在其所指位置插入0 值。string::erase
–删除 1 个或 1 段字符string::push_back
–追加 1 个字符string::pop_back
–删除最后 1 个字符,C++11 标准引入string::append
–追加字符或字符串string::operator+=
–追加,只有一个参数——字符指针、字符或字符串;不像 append() 一样可以追加参数的子串或若干相同字符string::copy
–拷贝出一段字符到 C 风格字符数组;有溢出危险string::resize
–改变(增加或减少)字符串长度;如果增加了字符串长度,新字符缺省为 0 值string::swap
–与另一个 string 交换内容string::replace
–替换子串;如果替换源数据与被替换数据的长度不等,则结果字符串的长度发生改变string::find
–前向搜索特定子串的第一次出现string::rfind
–从尾部开始,后向搜索特定子串的第一次出现string::find_first_of
–搜索指定字符集合中任意字符在 *this 中的第一次出现string::find_last_of
–搜索指定字符集合中任意字符在 *this 中的最后一次出现string::find_first_not_of
–*this 中的不属于指定字符集合的首个字符string::find_last_not_of
–*this 中的不属于指定字符集合的末个字符string::compare
–与参数字符串比较string::npos
–表示“未找到”,值为static const unsigned -1
std::operator+
–字符串连接std::operator!=
–不等比较std::operator==
–相等比较std::operator<
–小于比较std::operator<=
–小于等于比较std::operator>
–大于比较std::operator>=
–大于等于比较std::operator<<
–字符串内容写到输出流中std::operator>>
–从输入流中读取一个字符串std::getline
–从istream中读入一行或一段字符到string中std::swap
–交换两个string的内容。是std::swap算法针对std::basic_string的特化版本std::stoi
–字符串转为整形std::stol
–字符串转为长整形std::stoll
–字符串转为长长整形std::stoul
–字符串转为无符号长整形std::stoull
–字符串转为无符号长长整形std::stof
–字符串转为单精度浮点形std::stod
–字符串转为双精度浮点形std::stold
–字符串转为长双精度浮点形std::to_string
–整型、无符号整型、浮点型转化为stringstd::to_wstring
–整型、无符号整型、浮点型转化为wstringstd::hash<std::string>
–计算hash值std::hash<std::wstring>
–计算hash值std::hash<std::u16string>
–计算hash值std::hash<std::u32string>
–计算hash值C++14标准定义了如下的std::basic_string字面量:
示例:
#include <string>
#include <iostream>
int main()
{
using namespace std::string_literals;
std::string s2 = "abc\0\0def"; // forms the string "abc"
std::string s1 = "abc\0\0def"s; // form the string "abc\0\0def"
std::cout<<s1.size()<<std::endl; //output 8
std::cout<<s2<<std::endl;
std::cout<<s1<<std::endl;
}
C++11标准引入了4个std::hash函数模板的特化。用于以string为键值的hash寻址。
char_traits是一个traits类模板。用于抽象出给定字符类型的字符特性与字符串操作。char_traits用于明确(explicit)实例化一个std::basic_string
类模板。
例如,如果需要定义“两个字符相等”当且仅当“两个字符的大写形式相等”,就可以在std::char_traits<char>之上派生定义一个类,重载定义eq、lt、compare、find四个静态成员函数。再用此特性类作为第二个模板参数去实例化std::basic_string类模板。
从C++11开始,明确禁止用“写时复制”(Copy On Write)实现stl::string。因为这在并发时容易引发错误。如下例的注释:
#include <string>
int main()
{
std::string str1("hello world\n");
//p指向str1的数据区
const char * p = str1.data();
{
//str2和str1共享数据
auto str2( str1);
//访问导致str1复制数据,此时p和str2直线同一块区域
str1[0];
//str2离开作用域,调用析构函数,此时str2的RefCount为0,因此str2指向的内存被释放
}
//此时p为野指针,这是严重的bug
printf(p);
return 0;
}
现在的主流编译器与标准库基本都采用了小对象优化(small objects optimization,又叫 small buffer optimization),以节约动态分配内存开销。
#include <iostream>
#include <string>
int main()
{
std::string foo = "fighters";
std::string bar = "stool";
// "!=" compares string contents for inequality, even though they are different objects.
if(foo != bar)
{
std::cout << "The strings are different." << std::endl;
}
// Prints "stool fighters" by creating a temporary object, which is automatically freed.
std::cout << bar + " " + foo << std::endl;
return 0;
}
/*
Output:
The strings are different.
stool fighters
*/
由于字符串的拷贝操作与其字节长度成比例,是O(n)量级。且创建字符串的临时栈对象的成本开销。因此string
一般作为常量引用(reference-to-const)以避免不必要的拷贝:
void print_the_string(const std::string& str)
{
std::cout << str;
}
c_str()
成员函数返回string类的C语言风格字符串(即ASCII-零串)的指针,用于C语言字符串的互操作。如果不需要零结尾的字符串,那么成员函数data()
返回不一定是0结尾的字符串的内存地址。
Seamless Wikipedia browsing. On steroids.
Every time you click a link to Wikipedia, Wiktionary or Wikiquote in your browser's search results, it will show the modern Wikiwand interface.
Wikiwand extension is a five stars, simple, with minimum permission required to keep your browsing private, safe and transparent.