C++STL standard template library-String class
- 1. Introduction to STL
- Two, string class
1. Introduction to STL
1.1 What is STL?
STL (standard template libaray-standard template library): It is an important part of the C++ standard library. It is not only a reusable component library, but also a software framework that includes data structures and algorithms .
1.2 Six components of STL
Two, string class
2.1 Why learn string?
In C language, a string is a collection of some characters ending with'\0'. In order to facilitate operation, the C standard library provides some library functions of the str series, but these library functions are separated from the string. It is in line with the OOP idea, and the bottom space needs to be managed by the user, and you may visit it beyond the boundary if you don't pay attention.
In OJ, questions about strings basically appear in the form of the string class, and in routine work, the string class is basically used for simplicity, convenience, and speed. Few people use the string manipulation functions in the C library.
2.2 The string class in the standard library
- string is a string class representing a string
- The interface of this class is basically the same as that of a conventional container, and some conventional operations specifically used to manipulate string are added.
- String is actually at the bottom: alias of basic_string template class, typedef basic_string<char, char_traits, allocator>string;
- Cannot manipulate sequences of multibyte or variable length characters.
When using the string class, you must include the #include header file and using namespace std;
2.3 Common construction of string objects
Constructor name | Function Description |
---|---|
string() (emphasis) | Construct an empty string class object, that is, an empty string |
string(const char* s) (emphasis) | Use C-string to construct string class objects |
string(size_t n, char c) | The string class object contains n characters c |
string(const string&s) (emphasis) | Copy constructor |
2.4 Capacity operation of string objects
Function name | Function Description |
---|---|
size (emphasis) | Construct an empty string class object, that is, an empty string |
length | Use C-string to construct string class objects |
capacity | The string class object contains n characters c |
empty (emphasis) | Copy constructor |
clear (emphasis) | Clear valid characters |
reserve (emphasis) | Reserve space for strings |
resize (emphasis) | The number of valid characters should be n, and the extra space is filled with character c |
void TestString1()
{
string s("hello");
cout << s.size() << endl; //返回字符串中的有效字符,不包含'\0'
cout << s.length() << endl; //等同于size,但是通常不用length求有效字符
cout << s.capacity() << endl; //返回空间总大小,同样不包含'\0'
cout << s << endl; //string类对象支持cin输入和cout打印
// 将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小
s.clear();
cout << s.size() << endl;
cout << s.capacity() << endl;
// 将s中有效字符个数增加到10个,多出位置用'a'进行填充
// “aaaaaaaaaa”
s.resize(10, 'a');
cout << s.size() << endl;
cout << s.capacity() << endl;
// 将s中有效字符个数增加到15个,多出位置用缺省值'\0'进行填充
// "aaaaaaaaaa\0\0\0\0\0"
// 注意此时s中有效字符个数已经增加到15个
s.resize(15);
cout << s.size() << endl;
cout << s.capacity() << endl;
cout << s << endl;
// 将s中有效字符个数缩小到5个
s.resize(5);
cout << s.size() << endl;
cout << s.capacity() << endl;
cout << s << endl;
}
Assuming that the size of the space is not specified, the capacity will be expanded every time, which will bring computational overhead
// 利用reserve提高插入数据的效率,避免增容带来的开销
void TestPushBack()
{
string s;
size_t sz = s.capacity();
cout << s.capacity() << endl;
cout << "making s grow:\n";
for (int i = 0; i < 100; ++i)
{
s.push_back('c');
//查看扩容了几次
if (sz != s.capacity())
{
sz = s.capacity();
cout << "capacity changed: " << sz << '\n';
}
}
}
The application scenario of reserve is to solve the capacity increase defect of string. Assuming that we already know how much space to open up, we can directly specify the space size to avoid the overhead caused by capacity increase.
// 利用reserve提高插入数据的效率,避免增容带来的开销
void TestPushBackReserve()
{
string s;
s.reserve(100);
size_t sz = s.capacity();
cout << s.capacity() << endl;
cout << "making s grow:\n";
for (int i = 0; i < 100; ++i)
{
s.push_back('c');
//查看扩容了几次
if (sz != s.capacity())
{
sz = s.capacity();
cout << "capacity changed: " << sz << '\n';
}
}
}
Pay attention to the following issues when using reserve
void TestString3()
{
string s;
// 测试reserve是否会改变string中有效元素个数
s.reserve(100);
cout << s.size() << endl;
cout << s.capacity() << endl;
// 测试reserve参数小于string的底层空间大小时,是否会将空间缩小
s.reserve(50);
cout << s.size() << endl;
cout << s.capacity() << endl;
}
to sum up
-
The underlying implementation principle of size() and length() is exactly the same. The reason for introducing size() is to be consistent with the interfaces of other containers. In general, size() is basically used.
-
clear() only clears the valid characters in the string without changing the size of the underlying space.
-
Both resize(size_t n) and resize(size_t n, char c) change the number of valid characters in the string to n, the difference is that when the
number of characters increases: resize(n) is filled with 0 The element space of resize(size_t n, char c) uses the character c to fill the extra
element space . Note: When resize changes the number of elements, if the number of elements is increased, the underlying capacity may be changed
. If the number of elements is reduced, the total size of the underlying space will not change. -
reserve(size_t res_arg=0): Reserve space for string without changing the number of effective elements. When the parameter of reserve is less than
the total size of the underlying space of string, the server will not change the capacity. -
The difference between reserve and resize is that reserve only increases the capacity without changing the number of effective elements. Resize changes the capacity space and initializes the capacity space.
2.5 Access and traversal operations of string objects
Function name | Function Description |
---|---|
operator[] | Return the character at position pos, called by const string object |
begin+ end | begin to get the iterator of one character + end to get the iterator of the next position of the last character |
rbegin + render | begin to get the iterator of one character + end to get the iterator of the next position of the last character |
Range for | C++11 supports a more concise range for new traversal method |
<1> operator[]
void TestStringOperator1()
{
string s1("hello world");
cout << s1 << endl;
s1[0] = 'H';
cout << s1 << endl;
const string s2("hello c++");
// s2[0] = 'h'; 代码编译失败,因为const类型对象不能修改
}
<2> Iterator
For the iterator, we can temporarily regard it as a pointer
//迭代器
void TestStringIterator()
{
string s("hello world");
//三种遍历方式:
//以下三种方式除遍历string外还可修改string中的字符
//第一种使用较多
//1.for+operator[]
cout << "for+operator[]" << endl;
for (size_t i = 0; i < s.size() - 1; ++i)
{
cout << s[i] << " "<< endl;
}
//2.正向迭代器
cout << "2.正向迭代器" << endl;
string::iterator it = s.begin();
while (it != s.end())
{
cout << *it << endl;
++it;
}
//2.反向迭代器
cout << "2.反向迭代器"<<endl;
string::reverse_iterator rit = s.rbegin();
while (rit != s.rend())
{
cout << *rit << endl;
++rit;
}
//3.范围for
cout << "3.范围for" << endl;
for (auto ch : s)
{
cout << ch << endl;
}
2.6 Modification operations of string objects
Function name | Function Description |
---|---|
push_back | Insert the character c at the end of the string |
append | Append a string after the string |
operator+= (emphasis) | Append the string str after the string |
c_str (emphasis) | Return C format string |
find + npos (emphasis) | Find the character c from the position pos of the string, and return the position of the character in the string |
rfind | Find the character c from the position pos of the string, and return the position of the character in the string |
substr | Start at position pos in str, intercept n characters, and then return it |
<1> Insert characters at the end of the string
<2> String search
//找文件尾
void TestStringFind()
{
string s = "hello world";
s.push_back('!'); //字符串后尾插字符
cout << s << endl;
s.append("HELLO"); //字符串后追加字符串
cout << s << endl;
s += 'W'; //+=追加字符
cout << s << endl;
s += "ORLD"; //+=追加字符串
cout << s << endl;
s += s; //追加string对象
cout << s << endl;
string file1("string.cpp");
string file4("string.c.tar.zip");
//substr第二个参数可以不写,从前往后找
size_t pos = file1.find('.');
if (pos != string::npos)
{
cout << file1.substr(pos, file1.size() - pos) << endl;
}
//rfind从后往前找
size_t pos4 = file4.rfind('.');
if (pos4 != string::npos)
{
cout << file4.substr(pos4) << endl;
}
//分割域名
string url = "http://cplusplus.com/reference/string/string/find/";
cout << url << endl;
size_t pos5 = url.find(':'); //第一个冒号分割http
if (pos5 != string::npos)
{
cout << url.substr(0, pos5) << endl;
}
size_t pos6 = url.find('/', pos5 + 3); //pos5+3:c pos6:/
if (pos6 != string::npos) //分割网址cplusplus.com
{
cout << url.substr(pos5 + 3, pos6 - (pos5 + 3)) << endl;
}
cout << url.substr(pos6 + 1, string::npos) << endl;
//删除http
string copy = url;
cout << copy.erase(0, pos5 + 3) << endl;
}
note:
- When appending characters to the end of the string, the three implementations of s.push_back© / s.append(1, c) / s +='c' are similar. In general
, the += operation of the string class is used more, += Operations can not only concatenate single characters, but also concatenate strings. - When operating on the string, if you can roughly estimate how many characters to put, you can first reserve the space through reserve.
2.7 Non-member functions of the string class
function | Function Description |
---|---|
operator+ | Use it as little as possible, because the return by value results in low efficiency of deep copy |
operator>> (emphasis) | Input operator overloading |
operator << (Priority) | Output operator overloading |
getline (emphasis) | Get a line of string |
relational operators (emphasis) | Size comparison |