C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数, 但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问.

PS:注意,这个类独立于所使用的编码来处理字节:如果用来处理多字节或变长字符(如UTF-8)的序列,这个类的所有成员(如长度或大小)以及它的迭代器,将仍然按照字节(而不是实际编码的字符)来操作~
1. string是表示字符串的字符串类 2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。 3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char,char_traits, allocator>string; 4. 不能操作多字节或者变长字符的序列。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_constructor()
{
//构造空的字符串对象即空字符串
string s1;
//使用字符串构造字符串对象
string s2("hello world");
//拷贝构造,将s2拷贝给s3
string s3(s2);
//拷贝字符串,并且只拷贝5个字符
string s4("hello world", 5);
cout << "s1" << s1 << endl;
cout << "s2 = " << s2 << endl;
cout << "s3 = " << s3 << endl;
cout << "s4 = " << s4 << endl;
}
int main()
{
test_constructor();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_constructor()
{
//从下标为3的位置开始拷贝字符串,拷贝12个字符串
string s5("you are welcome", 3, 12);
//使用字符'*'填充对象s6,填充10个
string s6(10, '#');
string s7;
//赋值运算符重载
s7 = s5;
cout << "s5 = " << s5 << endl;
cout << "s6 = " << s6 << endl;
cout << "s7 = " << s7 << endl;
}
int main()
{
test_constructor();
return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_string_iterators()
{
string str("how are you");
//获取指向第一个字符的迭代器
std::string::iterator it = str.begin();
while(it != str.end())
{
cout << *it;
it++;
}
}
int main()
{
test_string_iterators();
return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_string_reverse_iterators()
{
string str("how are you");
//使用反向迭代器时需要指定类域
string::reverse_iterator rit = str.rbegin();
string::reverse_iterator ren = str.rend();
while(rit != str.rend())
{
cout << *rit;
++rit;
}
}
int main()
{
test_string_reverse_iterators();
return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_string_capacity()
{
string str("hello world");
//返回字符串的长度
cout << "size:>" << str.size() << endl;
cout << "length:>" << str.length() << endl;
//返回字符串所能触及的最大长度
cout << "max_size:>" << str.max_size() << endl;
//返回当前对象所分配的容量大小
cout << "capacity:>" << str.capacity() << endl;
//清空字符串但是不影响容量
str.clear();
cout << "size:>" << str.size() << endl;
cout << "capacity:>" << str.capacity() << endl;
//判断字符串是否为空
str = "hello world";
int result = str.empty();
cout <<"清空前:>" << result << endl;
str.clear();
cout <<"清空后:>" << str.empty() << endl;
//默认将capacity缩到15
str.shrink_to_fit();
cout << "size:>" << str.size() << endl;
cout << "capacity:>" << str.capacity() << endl;
}
int main()
{
test_string_capacity();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_string_resize()
{
string str("hello world");
//比size小则进行删除
str.resize(10);
cout << "size:>" << str.size() << endl;
cout << "capacity:>" << str.capacity() << endl;
cout << str << endl;
cout << endl;
//比size大但小于capacity会用改变size,并用\0插入
str.resize(13);
cout << "size:>" << str.size() << endl;
cout << "capacity:>" << str.capacity() << endl;
cout << str << endl;
//比capacity大,会先改变size的大小同时进行扩容
str.resize(20);
cout << "size:>" << str.size() << endl;
cout << "capacity:>" << str.capacity() << endl;
cout << str << endl;
}
int main()
{
test_string_resize();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_string_reserve()
{
string str("hello world");
cout << "size:>" << str.size() << endl;
cout << "capacity:>" << str.capacity() << endl;
cout << "reserver后" << endl;
cout << endl;
//比size小不变化
str.reserve(10);
cout << "size:>" << str.size() << endl;
cout << "capacity:>" << str.capacity() << endl;
cout << str << endl;
cout << endl;
//比size大但小于capacity也不发生变化
str.reserve(13);
cout << "size:>" << str.size() << endl;
cout << "capacity:>" << str.capacity() << endl;
cout << str << endl;
cout << endl;
//比capacity大才会进行扩容
str.reserve(20);
cout << "size:>" << str.size() << endl;
cout << "capacity:>" << str.capacity() << endl;
cout << str << endl;
}
int main()
{
test_string_reserve();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_string_element_access()
{
string s1("hello world");
for(size_t i = 0; i < s1.size(); i++)
{
cout << s1[i] << " ";
}
cout << endl;
for (size_t i = 0; i < s1.size(); i++)
{
cout << s1.operator[](i) << " ";
}
cout << endl;
//获取尾部元素
cout << s1.back() << endl;
//获取头部元素
cout << s1.front() << endl;
cout << s1.at(0) << endl;
}
int main()
{
test_string_element_access();
return 0;
}

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_string_Modifiers()
{
string s1("hello world");
string s2("bit");
//operator+=运算符重载
s1 += s2;
s1 += 'c';
s1 += "bit";
cout << s1 << endl;
cout << endl;
//append
s1.append(" hello world");
cout << s1 << endl;
//给对象s1分配新内容,并且代替当初的字符串内容
s1.assign(" xxxxxx");
cout << s1 << endl;
}
int main()
{
test_string_Modifiers();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_string_Modifiers()
{
string s1("hello world");
string s2("bit");
//在下标为5的位置插入字符串0
s1.insert(5, "0");
cout << s1 << endl;
cout << endl;
//从下标为5的位置开始抹除,抹除的长度为3
s1.erase(5, 3);
cout << s1 << endl;
cout << endl;
//交换两个字符串的内容
s1.swap(s2);
cout<<"s1 == " << s1 << endl;
cout<<"s2 == " << s2 << endl;
}
int main()
{
test_string_Modifiers();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_string_operatorions()
{
string s1("hello world");
string s2("bit");
//返回C类型的字符串
cout << s1.c_str() << endl;
cout << s2.c_str() << endl;
//find
//查找字符,默认从首元素开始
cout << s1.find(' ') << endl;
//查找字符,从下标为5的位置开始
cout << s1.find(' ', 5) << endl;
//查找字符串,返回出现该字符串的首字符位置,类似于strstr
cout << s1.find("world") << endl;
cout << endl;
//rind
//查找最后一次出现该字符的位置
cout << s1.rfind('l') << endl;
//查找最后一次出现该字符串的位置
cout << s1.rfind("wo") << endl;
cout << endl;
size_t position = s1.find(' ');
//从position + 1的位置开始取后面字符串
cout << s1.substr(position + 1);
}
int main()
{
test_string_operatorions();
return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
#include <string>
void test_string_Non_member_function_overloads()
{
string s1("hello world");
string s2("hello world");
string s3("hello xorld");
cout << (s1 == s2) << endl;
cout << (s1 > s2) << endl;
cout << endl;
//读取一行字符串
getline(cin, s1);
string::iterator it = s1.begin();
string::iterator end = s1.end();
cout << s1 << endl;
cout << endl;
//区间为左闭右开,反转字符串
reverse(it, end);
cout << s1 << endl;
}
int main()
{
test_string_Non_member_function_overloads();
return 0;
}
PS:这是在32位平台下进行验证滴,32位平台下,指针占4个字节
string总共占28个字节,内部结构稍微复杂些,先是有一个联合体,联合体用来定义string中字符串的存储空间:
union _Bxty
{ // storage for small buffer or pointer to larger one
value_type _Buf[_BUF_SIZE];
pointer _Ptr;
char _Alias[_BUF_SIZE]; // to permit aliasing
} _Bx;
g++下,string是通过写时拷贝实现的,string对象总共占4个字节,内部只包含了一个指针,该指针将来指向一块堆空间,内部包含了如下字段:
struct _Rep_base
{
size_type _M_length;
size_type _M_capacity;
_Atomic_word _M_refcount;
};好啦,uu们,string的这部分滴详细内容博主就讲到这里啦,如果uu们觉得博主讲的不错的话,请动动你们滴小手给博主点点赞,你们滴鼓励将成为博主源源不断滴动力,同时也欢迎大家来指正博主滴错误~