C++-STL-string

use of string

In C language, there is no concept of class. Strings are usually stored in character arrays for processing, and a large number of string processing functions are provided in the library, but they are not very useful compared with C++. , C++ encapsulates the string class, and the bottom layer is also a character array. On this basis, the class encapsulates a large number of methods for processing strings. Let's introduce them one by one
.
First recommend a website for C++ documentation: cplusplus
insert image description here
can see that the string class is actually typedef. The original class is called basic_string. Because there are many types of encoding, the space occupied by a character is different, and some are 1 byte. 2 bytes and some 4 bytes, so there are different string classes.
insert image description here
The most commonly used is the basic_string< char > class.

default member function

Constructor

insert image description here
You can see that there are many overloaded forms of constructors, and I will only demonstrate the most commonly used ones below.
1. Use string initialization

int main()
{
    
    
	string str = "hello string";
	cout << str << endl;
	return 0;
}

insert image description here
2. Copy construction

int main()
{
    
    
	string str = "hello string";
	cout << str << endl;
	string str1(str);
	cout << str1 << endl;
	return 0;
}

insert image description here
3. Use a section of the string class object to construct an interval

int main()
{
    
    
	string str1 = "hello string";
	string str2(str1, 0, 8);
	cout << str2 << endl;
	return 0;
}

insert image description here

4. Use the first few characters of the string to construct

int main()
{
    
    
	string str1("hello string", 5);
	cout << str1 << endl;
	return 0;
}

insert image description here

assignment operator overloading

insert image description here
1. The string class object is used as a parameter

int main()
{
    
    
	string str1;
	string str2 = "hello C++";
	str1 = str2;
	cout << str1 << endl;
	return 0;
}

insert image description here

2, the string as a parameter

int main()
{
    
    
	string str1;
	str1 = "hello C++";
	cout << str1 << endl;
	return 0;
}

insert image description here

3, a single character as a parameter

int main()
{
    
    
	string str1;
	str1 = 'C';
	cout << str1 << endl;
	return 0;
}

insert image description here

destructor

insert image description here

capcity-related functions

insert image description here

  • size与length
int main()
{
    
    
	string str1 = "hello world";
	cout << "size() : " << str1.size() << endl
		<<  "length() : " << str1.length() << endl;
	return 0;
}

insert image description here
In fact, the functions of these two functions overlap, and the implementation is exactly the same. It is more reasonable to use length for strings, but the size of the subsequent containers is used, so the size interface is also provided to unify the string class.

  • The max_size
    insert image description here
    string can reach the maximum length, in fact, returns the maximum value of the unsigned integer.

insert image description here

  • capcity
    capcity is to return its capacity

  • resize and reserve
    insert image description here
    resize is to re-adjust the size of the string. If the parameter passed in is larger than the current size, it will be expanded and initialized. If it is smaller than the current size, its effective length will be changed (the capacity will not change).

int main()
{
    
    
	string str1 = "hello world";
	str1.resize(20);
	str1.resize(5);
	return 0;
}

insert image description here
insert image description here
insert image description here
insert image description here

reserve readjusts its capacity, it will only work when the incoming parameter is greater than the current capacity, and when the incoming parameter is greater than the current capacity, the capacity will be expanded without initialization.

int main()
{
    
    
	string str1 = "hello world";
	cout << str1.capacity() << endl;
	str1.reserve(5);
	cout << str1.capacity() << endl;
	str1.reserve(20);
	cout << str1.capacity() << endl;
	return 0;
}

insert image description here

  • clear
    insert image description here
    clears the string

  • empty
    insert image description here
    Check whether the string is empty

Access related functions

insert image description here
The most commonly used is [ ] to access any element of the string. at() is similar to its function except that it checks for out-of-bounds. operator[ ] uses assertion checking, and at uses gentle checking.

int main()
{
    
    
	string str1("hello world");
	for (int i = 0; i < str1.size(); i++)
	{
    
    
		cout << str1[i] << " ";
	}
	cout << endl;
	for (int i = 0; i < str1.size(); i++)
	{
    
    
		cout << str1.at(i) << " ";
	}
	cout << endl;
	return 0;
}

insert image description here

Modify string related functions

insert image description here
1.
insert image description here
insert image description here
The functions of append and operator+= are the same, except that append has more interfaces, but append is not more commonly used than operator+=.
2. Tail insertion and tail deletion
insert image description here
insert image description here
3. Insert and delete at any position
insert image description here
insert image description here
4. Exchange two string objects
insert image description here

String class other functions

insert image description here
1, c_str
insert image description here
returns the address of the underlying maintenance string.

int main()
{
    
    
	string str1("hello string");
	const char* s = str1.c_str();
	cout << s << endl;
	return 0;
}

insert image description here
2, find and rfind
insert image description here
insert image description here

One is to search from front to back, and the other is to search from back to front. The search content can be characters, strings, and string objects. Returns the position subscript of the found string.

3.substr
insert image description here

The string cutting function returns a string object starting from position pos with a length of len, where nops is the maximum value of an unsigned integer. If the length is greater than the original string itself, then the string from pos position to the end will be returned.

insert image description here

4.
insert image description here
The compare function is actually not commonly used, mainly because the string class overloads a large number of relational operators.
insert image description here

non-member function

insert image description here
1. Overloading stream extraction and stream insertion operators

Since the string class is a self-defined type, cin and cout cannot be used to input and output it, so the >> and << operators must be overloaded.

2,getline
insert image description here

When using cin>> to read a string, it will stop when it encounters a space, so if we want to input a string with a space, there will be a problem, and the getline function can avoid this problem. It is read by default If '\n' is the end mark, the end mark can also be changed manually.

Analog implementation of string

1. General framework

namespace gy
{
    
    
	class string
	{
    
    
	public:
		string(const char* str = "")
			:_size(strlen(str))
		{
    
    
			_capcity = _size == 0 ? 4 : _size;
			_str = new char[_capcity + 1];
			strcpy(_str, str);
		}
	private:
		char* _str;
		size_t _size;
		size_t _capcity;
		static const size_t npos = -1;
	};
}

2. Copy constructor

string(const string& s)
			:_size(s._size)
			, _capcity(s._capcity)
{
    
    
	_str = new char[_capcity + 1];
	strcmp(_str, s._str);
}

3. Assignment operator overloading

string& operator=(const string& s)
{
    
    
	_size = s._size;
	_capcity = s._capcity;
	char* tmp = new char[_capcity + 1];
	strcpy(tmp, s._str);
	delete[] _str;
	_str = tmp;
	return *this;
}

4. Destructor

~string()
{
    
    
	delete[] _str;
	_str = nullptr;
	_size = _capcity = 0;
}

5, c_str function

const char* c_str()
{
    
    
	return _str;
}

6, size and capacity

size_t size() const
{
    
    
	return _size;
}
size_t capcity() const
{
    
    
	return _capcity;
}

Since such a function does not modify the content of the string, it is best to add const so that both ordinary objects and const objects can be called.

7,operator[ ]

char& operator[](size_t n)
{
    
    
	assert(n < _size);
	return _str[n];
}
const char& operator[](size_t n) const
{
    
    
	assert(n < _size);
	return _str[n];
}

8,reserve

void reserve(size_t n)
{
    
    
	if (n > _capcity)
	{
    
    
		char* tmp = new char[n + 1];
		strcpy(tmp, _str);
		delete[] _str;
		_str = tmp;
		_capcity = n;
	}
}

9,insert

insert overloads two versions, one for inserting characters and one for inserting strings

string& insert(size_t pos, char ch)
{
    
    
	assert(pos <= _size);
	//插入前检查是否需要扩容
	if (_size + 1 > _capcity)
		reserve(_size * 2);
	//挪动数据
	size_t end = _size;
	while (end >= pos)
	{
    
    
		_str[end + 1] = _str[end];
		--end;
	}
	_str[pos] = ch;
	_size++;
	return *this;
}

If you use this way of writing, you will find that the program keeps running and cannot stop when you are testing.
This is because the subscripts we use are all of size_t type. If pos is 0, when the data is moved for the last time, end is at 0 position. After moving – end, end will be reduced to -1, and -1 is for none For signed integers, it is the maximum value, so it will cause an infinite loop. So we have to write it differently.

string& insert(size_t pos, char ch)
{
    
    
	assert(pos <= _size);
	//插入前检查是否需要扩容
	if (_size + 1 > _capcity)
		reserve(_size * 2);
	//挪动数据
	size_t end = _size + 1;
	while (end > pos)
	{
    
    
		_str[end] = _str[end - 1];
		--end;
	}
	_str[pos] = ch;
	_size++;
	return *this;
}

insert string

When inserting strings, you also need to pay attention to the above infinite loop problem.

string& insert(size_t pos, const char* s)
{
    
    
	assert(pos <= _size);
	size_t lens = strlen(s);
	if (_size + lens > _capcity)
		reserve(_size + lens);
	//挪动数据
	size_t end = _size + lens;
	while (end > pos + lens - 1)
	{
    
    
		_str[end] = _str[end - lens];
		--end;
	}
	strncpy(_str, s, lens);
	_size += lens;
	return *this;
}

10,erase

string& erase(size_t pos, size_t len = npos)
{
    
    
	assert(pos < _size);
	//挪动数据
	if (len == npos || _size - pos <= len)
	{
    
    
		_str[pos] = '\0';
		_size = pos;
	}
	else
	{
    
    
		size_t begin = pos + len;
		while (begin <= _size)
		{
    
    
			_str[begin - len] = _str[begin];
			++begin;
		}
		_size -= len;
	}
	return *this;
}

11,push_back, pop_back, append

These interfaces can be reused using the above insert and erase.

void push_back(char ch)
{
    
    
	insert(_size, ch);
}
void pop_back()
{
    
    
	erase(_size - 1);
}
void append(const char* s)
{
    
    
	insert(_size, s);
}

12,operator+=

+= a character

void operator+=(char ch)
{
    
    
	push_back(ch);
}

+= string

void operator+=(const char* s)
{
    
    
	append(s);
}

These functions are reusing insert and erase. It can be seen that once insert and erase are implemented, a lot of work has been completed.

13,swap

The swap of the member function is very simple, it only needs to exchange the internal _str, _size, _capcity.

void swap(string& s)
{
    
    
	std::swap(_str, s._str);
	std::swap(_size, s._size);
	std::swap(_capcity, s._capcity);
}

14,find

find a character

size_t find(char ch,size_t pos = 0)
{
    
    
	assert(pos < _size);
	for (int i = pos; i < size(); i++)
	{
    
    
		if (_str[i] == ch)
			return i;
	}
	return npos;
}

find a string

size_t find(const char* s, size_t pos = 0)
{
    
    
	assert(pos < _size);
	char* res = strstr(_str + pos, s);
	if (!res)
		return npos;
	return res - _str;
}

15,substr

string substr(size_t pos, size_t len = npos)
{
    
    
	assert(pos < _size);
	string res;
	size_t curlen = len;
	if (len <= _size - pos || len == npos)
		curlen = _size - pos;
	char* tmp = new char[curlen + 1];
	strncpy(tmp, _str + pos, curlen);
	tmp[curlen] = '\0';
	res += tmp;
	delete[] tmp;
	return res;
}

16, Overloading relational operators

bool operator==(const string& str) const
{
    
    
	return strcmp(_str, str._str) == 0;
}
bool operator>(const string& str) const
{
    
    
	return strcmp(_str, str._str) > 0;
}
bool operator>=(const string& str) const
{
    
    
	return (*this > str) || (*this == str);
}
bool operator<(const string& str) const
{
    
    
	return !(*this >= str);
}
bool operator<=(const string& str) const
{
    
    
	return !(*this > str);
}
bool operator!=(const string& str) const
{
    
    
	return !(*this == str);
}

17. Overloaded stream insertion operator

friend ostream& operator<<(ostream& _cout, const string& str);//类内
ostream& operator<<(ostream& _cout, const string& str)
{
    
    
	for (int i = 0; i < str.size(); i++)
	{
    
    
		if (str[i] == '\0')
			cout << ' ';
		else
			cout << str[i];
	}
	return _cout;
}

18. Overloaded stream insertion operator

friend istream& operator>>(istream& _cin, string& str);//类内
istream& operator>>(istream& _cin, string& str)
{
    
    
	str.clear();
	char ch = cin.get();
	//缓冲区提高效率
	char tmp[128];
	int i = 0;
	while (ch != ' ' && ch != '\n')
	{
    
    
		tmp[i++] = ch;
		if (i == 127)
		{
    
    
			tmp[127] = '\0';
			str += tmp;
			i = 0;
		}
		ch = cin.get();
	}
	if (i != 0)
	{
    
    
		tmp[i] = '\0';
		str += tmp;
	}
	return _cin;
}

18. Forward iterator

iterator begin()
{
    
    
	return _str;
}
iterator end()
{
    
    
	return _str + _size;
}
const_iterator begin() const
{
    
    
	return _str;
}
const_iterator end() const
{
    
    
	return _str + _size;
}

Je suppose que tu aimes

Origine blog.csdn.net/Djsnxbjans/article/details/129907410
conseillé
Classement