C++ STL detailed string [C++]

function template

The principle of function templates

template <typename T> //模板参数 ——类型 
void Swap(T& x1, T& x2)
{
    
    
	T tmp = x1;
	x1 = x2;
	x2 = tmp;
}
int main()
{
    
    
	int a = 0, b = 1;
	double c = 1.1, d = 2.2;

	swap(a, b);
	swap(c, d);
	int* p1 = &a;
	int* p2 = &b;
	swap(p1, p2);
	return 0;
}

A function template is a blueprint. It is not a function itself, but a mold for the compiler to generate a specific type of function by using it. So in fact, the template is to hand over the repetitive things that we should have done to the compiler.
insert image description here

In the compiler compilation stage, for the use of template functions, the compiler needs to deduce and generate corresponding types of functions for calling according to the type of actual parameters passed in. For example: when using a function template with a double type, the compiler determines T as a double type through the deduction of the actual parameter type, and then generates a code that specifically handles the double type, and the same is true for the character type

insert image description here

Instantiation of function templates

When a function template is used with parameters of different types, it is called instantiation of the function template. Template parameter instantiation is divided into: implicit instantiation and explicit instantiation

1. Implicit instantiation : Let the compiler deduce the actual type of the template parameter according to the actual parameter

template<class T>
T Add(const T& left , const T& right)
{
    
    
	return left + right;
}
int main()
{
    
    

	int a1 = 10, a2 = 20;
	double d1 = 10.1, d2 = 20.2;
	//函数模板根据调用,自动推导模板参数的类型 ,实例化对应的参数 
		cout << Add(a1, a2) << endl;
		cout << Add(d1, d2) << endl;
	//实参传递的类型, 推演T的类型  
		cout << Add( a1, (int)d1  ) << endl;
		cout << Add( (double)a1, d1) << endl;
	//显示实例化 ,用指定的类型实例化 ,相当于隐式类型转换 
		cout << Add<int> (a1, d1) << endl;
		cout << Add<double>(a1, d1) << endl;

	return 0;
}

2. Explicit instantiation : Specify the actual type of the template parameter in <> after the function name

template<class T>
T Add(const T& left , const T& right)
{
    
    
	return left + right;
}
int main()
{
    
    

	int a1 = 10, a2 = 20;
	double d1 = 10.1, d2 = 20.2;
	//函数模板根据调用,自动推导模板参数的类型 ,实例化对应的参数 
		cout << Add(a1, a2) << endl;
		cout << Add(d1, d2) << endl;
	//实参传递的类型, 推演T的类型  
		cout << Add( a1, (int)d1  ) << endl;
		cout << Add( (double)a1, d1) << endl;
	//显示实例化 ,用指定的类型实例化 ,相当于隐式类型转换 
		cout << Add<int> (a1, d1) << endl;
		cout << Add<double>(a1, d1) << endl;

	return 0;
}
template<class T >
 T * Alloc(int n )
{
    
    
	 return new T[n];
}

 int main()
 {
    
    
	 //有些函数无法自动推导函数模板的类型,实例化对应的参数,只能显式实例化
	 double *p1 = Alloc <double>(10);
	 return 0;
 }

Matching Principles for Template Parameters

class template

//Class templates cannot be deduced and instantiated, so class templates are explicitly instantiated

class Stack
{
    
    
public :
	Stack(int capacity = 3)
	{
    
    
		_array= new  T[capacity];
			_size = 0;
		_capacity = 0; 
	}
	void Push(const T &  data)
	{
    
    
		_array[_size++] = data;
	}
	~Stack()
	{
    
    
		free(_array);
		_size = _capacity = 0;
	}
private :
	T * _array;
	int _size;
	int _capacity;
};
int main()
{
    
    
	Stack <int> s1(); // int 
	Stack <double> s2();//double 
	Stack <char> s3();//char
	//Stack <int ,doule> s2();


	return 0; 
}

The definition format of a class template

Separation of declaration and definition of function class templates

template<class T>


class Stack
{
    
    
public:
	//声明 
	Stack(int capacity );
	void Push(const T& data)
	{
    
    
		_array[_size++] = data;
	}
	~Stack()
	{
    
    
		free(_array);
		_size = _capacity = 0;
	}
private:
	T* _array;
	int _size;
	int _capacity;
};
//定义 
template<class T>
 Stack<T>::Stack(int capacity )
{
    
    
	_array = new  T[capacity];
	_size = 0;
	_capacity = 0;
}
int main()
{
    
    
	Stack <int> s1(); // int 
	Stack <double> s2();//double 
	Stack <char> s3();//char
	//Stack <int ,doule> s2();


	return 0;
}

For ordinary classes, the class name and type are the same, but for class templates, the class name and type are not the same. In the above code, Stack is the class name, but Stack<T> is the type

Instantiation of class templates

string

insert image description here

First, the definition of string

string();  //构造一个空字符串

string(const char* s);  //复制s所指的字符序列

string(const char* s, size_t n);  //复制s所指字符序列的前n个字符

string(size_t n, char c);  //生成n个c字符的字符串

string(const string& str);  //生成str的复制品

string(const string& str, size_t pos, size_t len = npos);  //复制str中从字符位置pos开始并跨越len个字符的部分

Example usage:

string s1;                     //构造空字符串
string s2("hello string");     //复制"hello string"
string s3("hello string", 3);  //复制"hello string"的前3个字符
string s4(10, 's');            //生成10个's'字符的字符串
string s5(s2);                 //生成s2的复制品
string s6(s2, 0, 4);           //复制s2中从字符位置0开始并跨越4个字符的部分

Two, string insertion

insert image description here

Use push_back for tail insertion

#include <iostream>
#include <string>
using namespace std;
int main()
{
    
    
	string s;
	s.push_back('C');
	s.push_back('X');
	s.push_back('Q');
	cout << s << endl; //CXQ
	return 0;
}

Insert using Insert
insert image description here

int main()
{
    
    
	string s("C");
	//insert(pos,str)在pos位置插入字符串str
	s.insert(1, "X");
	cout << s << endl;
	//insert(pos, string) ,在pos位置插入string对象 
	string t("Q");
	s.insert(2, t);
	cout << s << endl;
	//insert(pos, char)在pos位置插入char 
	s.insert(s.end(), 'A');
	cout << s << endl;
	return 0;
}

3. String splicing

Use the append function to complete the splicing of strings:

insert image description here

int main()
{
    
    
	string s1("A");
	string s2("B");
	//append(string)完成两个sting对象的拼接 
	s1.append(s2);
	
	cout << s1 << endl;
	

	//append(str)完成string对象和str字符串的拼接 
	s1.append("C");
	cout << s1 << endl;
	//append(n, char)将n个字符串拼接到string对象后面 
	s1.append(1, 'D');
	cout << s1 << endl;

	return 0;
}

4. Deletion of string

insert image description here

int main()
{
    
    
	string s("CXQ");
	s.pop_back();
	s.pop_back();
	cout << s << endl;

	return 0;
}

delete using erase

insert image description here

int main()
{
    
    
	string s("ABCDEFG");
	//erase (pos , n )删除pos位置开始的n个字符
	s.erase(2, 1);
	cout << s << endl;//ABDEFG
	//erase(pos)删除pos位置的字符
	s.erase(s.end() - 1);
	cout << s << endl;
	 
	//erase(pos1, pos2)删除[pos1pos2)上所有字符
	s.erase(s.begin() + 1, s.end());
	cout << s << endl;

	return 0;
}

Five, string search

1. Use the find function to search forward for the first match

insert image description here

int main()
{
    
    
	string s1("http://www.cplusplus.com/reference/string/string/find/");
	//find(string)正向搜索与string对象所匹配的第一个位置 
	string s2("www");
	size_t pos1 = s1.find(s2);
	cout << pos1 << endl;
	//find(str)正向搜索与str字符串所匹配的第一个位置 
	char str[] = "cplusplus.com";
	size_t pos2 = s1.find(str);
	cout << pos2 << endl;
	//find(char)正向搜索与char字符所匹配的第一个位置 
	size_t pos3 = s1.find('r');
	cout << pos3 << endl;
	return 0;

}

2. Use the rfind function to reverse search for the first match

insert image description here

int main()
{
    
    
	string s1("http://www.cplusplus.com/reference/string/string/find/");
	//rfind反向搜索与string对象所匹配的第一个位置 
	string s2("string");
	size_t pos1 = s1.rfind(s2);
	cout << pos1 << endl;
	//rfind(str)反向搜索与字符串str所匹配的第一个位置
	char str[] = "reference";
	size_t pos2 = s1.rfind(str);
	cout << pos2 << endl;
	//rfind(char)反向搜索与字符char所匹配的第一个位置 
	size_t pos3 = s1.rfind('/');
	cout << pos3 << endl;
	return 0;
}

Six, string comparison

Use the compare function to complete the comparison:
comparison rules:

1. If the value of the first unmatched character in the comparison string is smaller, or if all the comparison characters match but the comparison string is shorter, then return a value less than 0.

 2. If the value of the first unmatched character in the comparison string is larger, or if all the comparison characters match but the comparison string is longer, return a value greater than 0.

 3. If the two strings compared are equal, 0 is returned.
insert image description here

int main()
{
    
    
	string s1("hello world");
	string s2("hello Linux"); 
	cout << s1.compare(s2) << endl;//1
	//ell 与hello Linux 比较 
	cout << s1.compare(1, 3, s2) << endl;//-1
	//hello与hello比较
	cout << s1.compare(0, 4, s2, 0, 4) << endl;//0

	return 0;
}

Note: In addition to supporting comparisons between string classes, the compare function also supports string class and string comparisons

Seven, string replacement

Use the replace function to complete string replacement:

insert image description here

int main()
{
    
    
	string s("hello world");
	//replace(pos, len, str)将pos开始的len个字符替换成str 
    s.replace(6, 5, "Linux");//hello Linux 
	cout << s << endl;
	//replace(pos, len, n, char)将pos位置开始的len个字符替换成n个字符char 
	s.replace(10, 1, 3, '!');
	cout << s << endl;//hello Linu!!!
	return 0;

}

Eight, string exchange

Use the swap function to complete the exchange of two string classes:
insert image description here

int main()
{
    
    
	string s1("hello");
	string s2("Linux");
	//使用string类的成员函数swap交换s1和s2
	s1.swap(s2);
	cout << s1 << endl;
	cout << s2 << endl;
	//使用非成员函数swap交换s1和s2
	swap(s1, s2);
	cout << s1 << endl;
	cout << s2 << endl;
	return 0;
}

Nine, the size and capacity of string

1. Use the size function or length function to obtain the number of currently valid characters
insert image description here

int main()
{
    
    
	string s("hello");
	cout << s.size() << endl;
	cout << s.length() << endl;
	return 0;
}

2. Use the max_size function to obtain the maximum number of characters that a string object can contain

int main()
{
    
    
	string s("hello");
	cout << s.size() << endl;
	cout << s.length() << endl;
	cout << s.max_size() << endl;
	return 0;
}

3. Use the capacity function to obtain the size of the storage space allocated by the current object
insert image description here

int main()
{
    
    
	string s("hello");
	cout << s.size() << endl;
	cout << s.length() << endl;
	cout << s.max_size() << endl;
	cout << s.capacity() << endl;
	return 0;
}

4. Use resize to change the number of valid characters of the current object
insert image description here

Resize rules:
 1. When n is greater than the current size of the object, expand the size to n, and the expanded character is c. If c is not given, it defaults to '\0'.
 2. When n is smaller than the current size of the object, reduce the size to n.

int main()
{
    
    
	string s1("hello");
	s1.resize(30);
	cout << s1 << endl;
	//resize(n)n大于对象当前的size时,将size扩大到n,扩大的字符默认为'\0'
	cout << s1.capacity() << endl;
	cout << s1.size() << endl;
	

	string s2("ABCD");
	// resize(n, char)n大于对象当前的size时,将size扩大到n,扩大的字符为char
	s2.resize(20, 'x');
	cout <<s2<< endl; //ABCDxxxxxxxxxxxxxxxx
	cout << s2.size() << endl; //20
	cout << s2.capacity() << endl; //当前容量 


	string s3("ABCD");
	//resize(n)n小于对象当前的size时,将size缩小到n
	s3.resize(2);
	cout << s3 << endl;
	cout << s3.capacity() << endl;//当前容量
	cout << s3.size() << endl;//当前有效字符个数 


	return 0;
}

Note: If the given n is greater than the current capacity of the object, the capacity will also be expanded according to its own growth rules.

5. Use reserve to change the capacity of the current object

Reserve rules:
 1. When n is greater than the current capacity of the object, expand the capacity to n or greater than n.
 2. When n is less than the current capacity of the object, do nothing.

int main()
{
    
    
	string s("ABCD");
	cout << s << endl;
	cout << s.size() << endl;//当前有效字符的个数 
	cout << s.capacity() << endl; //当前容量 

		//reverse(n)当n大于对象当前的capacity时,将当前对象的capacity扩大为n或大于n
	s.reserve(20);
	cout << s << endl;
	cout << s.size() << endl;//当前有效字符的个数 
	cout << s.capacity() << endl; //当前容量 

	// reverse(n)当n小于对象当前的capacity时,什么也不做
	s.reserve(2);
	cout << s << endl;
	cout << s.size() << endl;//当前有效字符的个数 
	cout << s.capacity() << endl; //当前容量 

	return 0;
}

Note: this function has no effect on the size of the string and cannot change its content

6. Use clear to delete the content of the object, and the object becomes an empty string after deletion
insert image description here

int main()
{
    
    
	string s("hello");
	cout << s << endl;
	s.clear();
	cout << s << endl;
	return 0;
}

7. Use empty to judge whether the object is empty
insert image description here

int main()
{
    
    
	string s("hello");
	cout << s << endl;
	cout << s.empty() << endl;//判断对象是否为空 
	s.clear();//删除对象里的内容,对象将变为空字符串 
	cout << s.empty() << endl;//判断对象是否为空 
	return 0;
}

10. Access to elements in string

insert image description here

1. [ ] + subscript
 Because the string class overloads the [ ] operator, we can directly use [ ] + subscript to access the elements in the object. And this overload uses reference return, so we can modify the element at the corresponding position through [ ]+subscript.

int main()
{
    
    
	string s("ABCD");
	//[]+下标访问对象元素
	for (size_t i =0; i < s.size(); i++)
	{
    
    
		cout << s[i] << endl;;
	}
	//[]+下标修改对象元素内容
	for (size_t i= 0; i < s.size(); i++)
	{
    
    
		s[i] = 'x';
	}
	cout << s << endl;
//	string s1("hello world");
//	char s3[] = "hello world";
//	s3[1]++; //  等价于*(s3+1)
//	s1[1]++; // 等价于s1.operator[](1);
	return 0;
}

2. Use at to access the elements in the object
 because the at function is also used to return the reference, so we can also modify the element at the corresponding position through the at function.

insert image description here

int main()
{
    
    
	string s("ABCD");
	for (size_t i = 0; i < s.size(); i++)
	{
    
    
		cout << s.at(i);
	}
	cout<< endl;
	for (size_t i = 0; i < s.size(); i++)
	{
    
    
		s.at(i) = 'x';
	}
	cout << s << endl;
	return 0;

}

3. When using the scope for to access the elements in the object,
 special attention should be paid to: if the element of the object needs to be modified through the scope for, the type of the variable e used to receive the element must be a reference type, otherwise e is just a copy of the object element. The modification of e does not affect the elements of the object.

The bottom layer of the range for is replaced by a forward iterator, and the range for has limitations: the range for cannot support reverse iterators

Forward iterator: iterator const_iterator (read only)

insert image description here

Reverse iterator: reverse_iterator, const_reverse_iterator (read only)

#include <iostream>
#include <string>
using namespace std;
int main()
{
    
    
	string s("CSDN");
	//使用范围for访问对象元素
	for (auto e : s)
	{
    
    
		cout << e;
	}
	cout << endl; //CSDN

	//使用范围for访问对象元素,并对其进行修改
	for (auto& e : s) //需要修改对象的元素,e必须是引用类型
	{
    
    
		e = 'x';
	}
	cout << s << endl; //xxxx
	return 0;
}

4. Use an iterator to access elements in an object

int main()
{
    
    
	string s1("ABCD");
	//使用迭代器访问对象元素
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
    
    
		cout << *it <<" ";
		++it; 
	}
	cout << endl;

	//使用迭代器访问对象元素,并对其进行修改
	string s2("QWER");
	string::iterator it2 = s2.begin();
	while (it2 != s2.end())
	{
    
    
		*it2 += 1;
		it2++;
	}
	cout << s2;
	return 0;

}

insert image description here

Iterator provides a unified way to access and modify the data in the container, and the algorithm can process the data in the container through the iterator

Eleven, the use of operators in string

1. operator= The = operator
 is overloaded in the string class, and the overloaded = operator supports the assignment of the string class, the assignment of strings, and the assignment of characters.

int main()
{
    
    
	string s1;
	string s2("ABCD");
	//支持string类的赋值
	s1 = s2;
	cout << s1 << endl;
	//支持字符串的赋值
	s1 = "hello";
	cout << s1 << endl;
	//支持字符的赋值
	s1 = 'X';
	cout << s1 << endl;

	return 0;
}

2. operator+= The
 += operator is overloaded in the string class, and the overloaded += operator supports the compound assignment of the string class, the compound assignment of strings and the compound assignment of characters.

int main()
{
    
    
	string s1;
	string s2("hello");
	//支持string类的复合赋值
	s1 += s2;
	cout << s1 << endl;
	//支持字符串的复合赋值
	s1 += " world";
	cout << s1 << endl;
	//支持字符的复合赋值
	s1 += "X";
	cout << s1 << endl;
	return 0;
}

3. The + operator
 is overloaded in the operator+ string class, and the overloaded + operator supports the following types of operations:
 string class + string class
 string class + string string
 + string class
 string class + character
 character + string class
They all return a string class object after being added.

int main()
{
    
    
	string s;
	string s1("ABCD");
	string s2("QWER");
	char str[] = "DFGH";
	char ch = '!';
	//string类 + string类
	s = s1 + s2;
	cout << s << endl;
	//string类 + 字符串
	s = s1 + str;
	cout << s << endl;
	//字符串 + string类
	s = str + s1;
	cout << s << endl;
	//string类 + 字符
	s = s1 + ch;
	cout << s << endl;
	//字符+string类
	s = ch + s1;
	cout << s << endl;
	return 0;
}

4、operator>> 和 operator<<

insert image description here

The >> and << operators are also overloaded in the string class, which is why we can directly use >> and << to input and output the string class.

int main()
{
    
    
	string s;
	cin >>s ;//输入
	cout << s;//输出 
	return 0;
}

5.
 A series of relational operators are also overloaded in the relational operators string class, which are ==, !=, <, <=, >, >=. The overloaded relational operators support the relational comparison between the string class and the string class, the relational comparison between the string class and the string, and the relational comparison between the string and the string class.

int main()
{
    
    
	string s1("abcd");
	string s2("abde");
	cout << (s1 > s2) << endl; //0
	cout << (s1 < s2) << endl; //1
	cout << (s1 == s2) << endl; //0
	return 0;
}

Note: These overloaded relational comparison operators compare the ASCII code values ​​​​of the corresponding characters.

12. Functions related to iterators in string

1. Functions related to forward iterators
insert image description here

begin function: returns an iterator pointing to the first character of the string.

end function: Returns an iterator pointing to the end character of the string, ie '\0'.
insert image description here

int main()
{
    
    
	string s("hello string");

	//正向迭代器
	string::iterator it1 = s.begin();
	while (it1 != s.end())
	{
    
    
		cout << *it1;
		it1++;
	}
	cout << endl;
	return 0;
}

2. The function related to the reverse iterator
rbegin function: returns the reverse iterator pointing to the last character of the string.
insert image description here

rend function: Returns a reverse iterator pointing to the theoretical element preceding the first character of the string.
insert image description here

int main()
{
    
    
	string s("hello string");
	//反向迭代器
	string::reverse_iterator rit = s.rbegin();
	while (rit!= s.rend())
	{
    
    
		cout << *rit;
		rit++;
	}
	cout << endl;
	return 0;
}

13. Conversion between string and string

1. Converting a string to a string
 Converting a string to a string is very simple, as mentioned earlier when we talked about the definition of string.

#include <iostream>
#include <string>
using namespace std;
int main()
{
    
    
	//方式一
	string s1("hello world");

	//方式二
	char str[] = "hello world";
	string s2(str);

	cout << s1 << endl; //hello world
	cout << s2 << endl; //hello world
	return 0;
}

2. Use c_str or data to convert string to string
insert image description here
Difference:

In C++98, c_str() returns a const char* type, and the returned string will end with a null character.
In C++98, data() returns a const char* type, and the returned string is not null-terminated.
But in the C++11 version, c_str() is used the same as data().

int main()
{
    
    
	//将string 转换为字符串 
	string s("hello world ");
	const char* str1 = s.data();
	const char* str2 = s.c_str();
	cout << str1 << endl;
	cout << str2 << endl;

	return 0;
}

14. Extraction of substrings in string

insert image description here

int main()
{
    
    
	string s1("abcdef");
	string s2;
	//substr(pos, n)提取pos位置开始的n个字符序列作为返回值
	s2 = s1.substr(2, 4);
	cout << s2 << endl;
	
	return 0;
}

2. Use the copy function to copy the substring of string into a character array
insert image description here

int main()
{
    
    
	string s("abcdef");
	char str[20];
	//copy(str, n, pos)复制pos位置开始的n个字符到str字符串
	size_t lenth=s.copy(str, 4, 2);
	//copy函数不会在复制内容的末尾附加'\0',需要手动加
	str[lenth] = '\0';
	cout << str << endl;
	return 0;
}

15. The getline function in string

We know that when using >> for input operations, when >> reads a space, it will stop reading. Based on this, we will not be able to use >> to read a string of strings containing spaces into the string object.

At this time, we need to use the getline function to complete the reading operation of a string of strings containing spaces.
Usage one:
insert image description here

The getline function stores the characters extracted from the istream into str until the newline character '\n' is read.

#include <iostream>
#include <string>
using namespace std;
int main()
{
    
    
	string s;
	getline(cin, s); //输入:hello CSDN
	cout << s << endl; //输出:hello CSDN
	return 0;
}

insert image description here
The getline function stores the characters extracted from is into str until the delimiter delim or the newline character '\n' is read.

int main()
{
    
    
	string s;
	getline(cin, s, 'D');
	cout << s << endl;
	return 0;
}

If you think this article is helpful to you, you might as well move your fingers to like, collect and forward, and give Xi Ling a big attention. Every
support of yours will be transformed into the driving force for me to move forward! ! !

insert image description here

Guess you like

Origin blog.csdn.net/qq_73478334/article/details/130957235