String class usage in C++


String class

在C语言中,我们对于对于字符数组的认识,仅仅局限于字符串,我们对于该数组进行一些操作的时候,往往要配合str系列的库函数来使用,但是这些库函数比较繁琐,底层空间需要用户来维护,有可能会在操作中越界访问。

The string class is provided in C++ to improve the use and processing of strings

Summarize:

  • The string type is a string class that represents strings
  • The interface of this class is basically the same as that of a conventional container, and some conventional operations specially used to manipulate strings are added to it.
  • String is actually at the bottom: an alias of the basic_string template class, typedef basic_string<char, char_traits, allocator>string;
  • Sequences of multibyte or variable-length characters cannot be manipulated.

Usage of String

我们对于String的使用从string的构造开始

The construction method of string class object

Four construction methods:

1. string( ) is constructed with empty parameters, and an empty string type is obtained

2. string (const char * s) uses C-string to construct string class objects, that is, pass a string "xxx" as a parameter

3. string (size_t n, char c) means to get a string of n c characters

4. string (const string& s) means to get a new string object by copying the constructor

下面是代码演示:

int main()
{
    
    
    string s1;   //得到空字符串
    string s2("hello world!!!");  //字符串内容为hello world!!!\0
    string s3(s2);  //拷贝构造函数,数值一样,地址不同
    string s4(10,'c');//十个字符为c的连起来的字符串
    return 0;
}

Capacity operations of the string class

function name Function Description
size Returns the effective character length of the string
length Returns the effective character length of the string
capacity Return the total size of the space
empty Check whether the string is an empty string, if it is empty, return true, otherwise return false
clear empty string
reserve Expansion, reserve enough space for the string
resize Set the number of valid characters, the extra space is replaced by '\0'

code demo

The difference between size and length

size()和length()方法底层实现的原理是一样的,只是为了与其他STL容器接口保持一致,才又加入了size(),以后一般情况下,直接使用size()即可

#include<iostream>
#include<string>
using namespace std;  //需要导入这些头文件以及展开std命名空间,下文不再一一写入代码段
void test11()
{
    
    
	string s("hello world");
	cout << s.size() << endl; //11
	cout << s.length() << endl;//11
}
int main()
{
    
    
	test11();

	return 0;
}

insert image description here

The use of capacity

capacity在不同的环境下的初始化的数值是不同的,在VS下我们根据下面代码可知,初始值为15,后序大概为1.5倍扩容,在Linux下初始值从0开始,。后序大概为2倍扩容。

void test12()
{
    
    
	//测试capacity
	String::string s;
	int num = s.capacity();
	cout << num << endl;
	for (int i = 0; i < 100; i++)
	{
    
    
		s += i;
		if (num != s.capacity())
		{
    
    
			cout << "capacity改为:" << s.capacity() << endl;
		}
		num = s.capacity();
	}
}
int main()
{
    
    
	test12();

	return 0;
}

insert image description here

The use of empty and clear

empty是用来判断当前字符串是否为空值(空串),真返回1,假返回0

clear用来清理字符串内容的,实际上是通过'\0'来实现的,会改变size的数值为0,capacity不会改变

void test13()
{
    
    
	string s("hello world");
	//检验empty的使用
	cout << s.empty() << endl;
	s.clear(); //当清空clear字符串s之后,再通过empty判空
	cout << s.empty() << endl;
	
	//empty返回为0表示假,返回为1表示真

	//判断clear之后是否size以及capacity发生改变
	string s1("hello world");
	cout << "当前capacity为:"<<s1.capacity() << endl;
	cout << "当前size为:" <<s1.size() << endl;
	//清理clear
	s1.clear();
	cout << "当前capacity为:" << s1.capacity() << endl;
	cout << "当前size为:" << s1.size() << endl;
}
int main()
{
    
    
	test13();

	return 0;
}

insert image description here

Use of reserve and resize

reserve是用来扩容更改capacity的,reserve在VS中只能向上扩容,不能缩容(减小),且不会改变size的大小

resize是用来改变字符串长度大小的,不管如何要满足size<=capacity,所以resize底层会在更改size大小前调用reserve来判断此时是否需要扩容,所以可能会影响capacity的大小

//capacity的大小只能是在15 31 ...这样的取值,保证大概1.5倍扩容,向上扩容
void test14()
{
    
    
	string s("hello world");
	cout << "原始数值" << endl;
	cout << "当前capacity为:" << s.capacity() << endl;
	cout << "当前size为:" << s.size() << endl;
	//验证reserve和resize
	s.reserve(20);
	cout << "使用reserve扩容后:" << endl;
	cout << "当前capacity为:" << s.capacity() << endl;
	cout << "当前size为:" << s.size() << endl;
	s.resize(20);
	cout << "使用resize更改size后:" << endl;
	cout << "当前capacity为:" << s.capacity() << endl;
	cout << "当前size为:" << s.size() << endl;
	cout << endl;
	//如果此时我们通过reserve缩容(减小当前容量)
	s.reserve(10000);
	cout << "缩容为10:结果如下" << endl;
	cout << "当前capacity为:" << s.capacity() << endl;
	cout << "当前size为:" << s.size() << endl;

	//那么我们继续缩小size
	s.resize(100);
	cout << "缩小size为5:结果如下" << endl;
	cout << "当前capacity为:" << s.capacity() << endl;
	cout << "当前size为:" << s.size() << endl;
}
int main()
{
    
    
	test14();
	return 0;
}

insert image description here

shrink_to_fit()

一般capacity扩容之后,不会再缩容,但是通过shrink_to_fit将容器的内部存储空间缩小到恰好容纳当前元素数量,以节省不必要的内存空间

shrink_to_fit使得capacity==size

Summarize

  1. The underlying implementation of size() and length() is the same, because in order to be compatible with other STL containers, the use of size() is added, and size() is generally used in the future
  2. clear() only clears the valid characters in the string, and does not change the size of the underlying space
  3. Both resize(size_t n) and resize(size_t n, char c) can change the size, but for the extra space, the former is filled with '\0' by default, the latter is filled with the specified character c, and the others are consistent.
  4. When resize changes the number of elements, if the number of elements is increased, the size of the underlying capacity may be changed. If the number of elements is reduced, the total size of the underlying space remains unchanged. That is size<=capacity
  5. reserve(size_t res_arg=0): reserve space for string, without changing the number of valid elements. When the parameter of reserve is smaller than the total size of the underlying space of string, reserver will not change the capacity.

Access to string class objects

我们有四种方法来对于string对象进行访问

function name Function Description
operator[ ] Returns the character at the specified position, const string class object call
begin + end begin( ) gets the iterator of the first element of the string object+end( ) gets the iterator of the next position of the last character
rbegin+rend rbegin gets the iterator of the last character +rend gets the iterator of the previous position of the first character of the string object
range for (enhanced for) It is a for loop traversal method supported by C++11, the essence is to call the iterator
void test15()
{
    
    	
	string s("hello world");
	//1.operator[] 访问,可以赋值  和数组一样
	cout << s[0] << endl;
	
	//2.begin 和 end 的使用   迭代器类似于指针的使用
	string::iterator it = s.begin();
	//auto it =s.begin();   可以用auto智能指针接收
	while(it!=s.end())
	{
    
    
		cout << *it << "";
		++it;
	}
	cout << endl;
	
	//3.rbegin和end的使用,就是反向遍历
	string::reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
    
    
		cout << *rit << "";
		++rit;   //反向遍历也是要++rit迭代器
	}
	cout << endl;

	//4.范围for
	for (auto ch : s)
	{
    
    
		cout << ch << "";  //范围for只能正向遍历
	}
	cout << endl;
}
int main()
{
    
    
	test15();
	return 0;
}

insert image description here

注意:反向迭代器和正向迭代器的rit/it都是++

Modification operation of string class object

function name Function Description
push_back Insert the character c at the end of the string
append Append a string str after the string
operator+= Append the string str after the string
c_str Returns a string in C format, that is, const char* (char pointer)
find+npos Find the character c backward from the position pos of the string, and return the position of the character in the string
rfind Find the character c forward 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 return them
insert Insert the string str at the position specified by pos. Many insert usages are commonly used as follows.
earse Starting at position pos, delete n characters

use of functions

push_back and append and operator+=

都是在string类对象尾部,添加字符或者字符串,push_back添加字符C,append以及operator+=添加字符串

void test16()
{
    
    
	string s;//空串
	//push_back的使用
	s.push_back('1');
	s.push_back('2');
	s.push_back('3');
	s.push_back('4');
	s.push_back('5');
	for (auto ch : s)
	{
    
    
		cout << ch << " ";
	}
	cout << endl;
	//append
	s.append("hello world");
	for (auto ch : s)
	{
    
    
		cout << ch << " ";
	}
	cout << endl;

	//3.operator+=
	s += "abcdefg";
	for (auto ch : s)
	{
    
    
		cout << ch << " ";
	}
}
int main()
{
    
    
	test16();
	return 0;
}

insert image description here

Use of c_str

c_str实际上就是将c++的string类型与C语言中的char* 兼容,因为在C语言中char* 字符数组表示的就是字符串。所以c_str返回的就是C语言中的const char* 类型

void test17()
{
    
    
    //const char* c_str() const;
	string s("hello world");
	cout << s.c_str() << endl;//c_str主要就是兼容C语言 返回的是const char*字符指针类型
}
int main()
{
    
    
	test17();
	return 0;
}

Use of find and rfind

find正向查找,rfind逆向查找,都可以指定pos位置作为起点,向后,向前查找指定字符C或者字符串,找到便返回下标位置,找不到返回的是npos也就是-1

void test18()
{
    
    
	string s("hello world");
	int pos = s.find('h');  //如果找不到返回的是npos 也就是-1
	cout << pos << endl;
	pos = s.find('l', 0);
	cout << pos << endl;
	pos = s.find('l', 6);
	cout << pos << endl;
	pos = s.find("hello");
	cout << pos << endl;

	//rfind的使用,就是从后向前开始查找
	string s1("123456 123456");
	pos = s1.rfind("123456");  //7
	cout << pos << endl;

	pos = s1.rfind('1');  //7
	cout << pos << endl;

	pos = s1.rfind('1',5);  //0
	cout << pos << endl;

}
int main()
{
    
    
	test18();
	return 0;
}

insert image description here

The use of substr

两个参数,表示起始位置和截止位置,前闭后开 [) 截止位置为缺省参数赋值npos

1. s.substr(5) 表示从下标为5的位置开始截取到字符串s的末尾

2. s.substr(0,5) 表示截取[0,5)的s字符串

void test19()
{
    
    
	//string substr (size_t pos = 0, size_t len = npos) const;
	string s("hello world");
	cout << s << endl;
	s.substr(5);  //在1str中从pos位置开始,截取n个字符,然后将其返回
	cout << s.substr(5) << endl;
	cout << s.substr(0, 5) << endl;
}
int main()
{
    
    
	test19();
	return 0;
}

insert image description here

usage of insert

insert有很多种方法,但是常用的就那些,比如在pos位置上插入字符串str,在pos位置上插入字符串str并指定该插入该字符串的元素个数,在pos位置上插入字符串str并指定从该字符串的subpos位置开始插入sublen字符,或者是

Commonly used four usages

  • string& insert (size_t pos, const char* s); Insert the string str at position pos

  • string& insert (size_t pos, const char* s, size_t n); Insert the string str at position pos and specify the number of characters to be inserted into the string

  • string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);

    ​ Insert the string str at position pos and specify to insert sublen characters from the subpos position of the string

  • string& insert (size_t pos, size_t n, char c); Insert n characters c at position pos

void test21()
{
    
    
	string s("hello world");
	//string& insert (size_t pos, const char* s);  
	//表示在pos位置上插入字符数组s
	s.insert(1, "123");
	cout << s << endl;
	//string& insert (size_t pos, const char* s, size_t n);
	//表示在pos位置上插入s字符数组的前n个字符
	s.insert(1, "123456",10);   //如果n超过原有数组的长度,将多出来的字符位置填充'\0',相当于将这个"123456"字符串扩容为"123456\0\0\0\0" 然后插入到s对象pos位置
	cout << s.size() << endl;
	// string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);
	s.clear();
	cout << s << endl;
	s.insert(0, "123456");  //如果插入数值pos的位置越界,那么就会报错
	cout << s.size() << endl;
	cout << s << endl;
	//string& insert (size_t pos, size_t n, char c);
	//表示在pos位置上,插入n个字符c
	s.insert(0, 10, 'c');
	cout << s << endl;
}
int main()
{
    
    
	test21();
	return 0;
}

insert image description here

use of earse

string& erase (size_t pos = 0, size_t len = npos); 从pos位置删除len个字符,len默认npos,即删除pos位置之后所有元素

iterator erase(iterator p); 删除指定迭代器位置的字符

iterator erase (iterator first, iterator last); 删除在[first,last) 之间的字符

void test22()
{
    
    
	//1. string& erase (size_t pos = 0, size_t len = npos);
	string s("hello world");
	cout << s << endl;
	s.erase(0, 6);
	cout << s << endl;
	
	//2. iterator erase(iterator p);
	s.erase(s.begin() + 3);  //删除该迭代器位置的元素
	cout << s << endl;

	//3. iterator erase (iterator first, iterator last);
	s.erase(s.begin() + 1, s.end());
	cout << s << endl;
}
int main()
{
    
    
	test22();
	return 0;
}

insert image description here

pop_back

作用为删除字符串的最后一个字符

usage of replace

replace就是对于指定区间的字符进行替换,替换为另一个字符串的内容,参数多样,顺序一般为pos,len,str,subpos,sublen,分别表示replace的字符串的指定下标,长度,要替换为的字符串str,str开始的位置,截取str的长度

主要理解就是,replace替换,需要指定空间,然后替换为str字符串形式,至于替换str字符串的那一部分,由subpos和sublen决定,从左到右,最少三个参数 pos len str。

可以由迭代器来表示范围(pos和len)如:string& replace (iterator i1, iterator i2, const char* s, size_t n);最后参数n表示替换s字符数组的个数

void test23()
{
    
    
	string s("hello world");
	//string& replace (size_t pos,  size_t len,  const string& str);
	cout << s << endl;//hello world
	s.replace(0, 2, "123456");//将pos位置向后的len个字符,替换成str字符串 //123456llo world
	cout << s << endl;
	//string& replace (iterator i1, iterator i2, const string& str); 
	//可以使用迭代器,也能实现
	string s1("hello world"); 
	cout << s1 << endl;
	s1.replace(s1.begin(), s1.begin() + 2, "123456");  //123456llo world  
	cout << s1 << endl;

	//string& replace (size_t pos,  size_t len,  const string& str,size_t subpos, size_t sublen);
	//就是将pos位置向后的len个字符,替换成从subpos位置上长度为sublen的str字符串的字符内容
	//相当于substr之后的字符串替换pos的len个字符
	string s2("hello world");
	cout << s2 << endl;//hello world
	s2.replace(0,2,"123456",0,2);  //12llo world
	cout << s2 << endl;

	//string& replace (size_t pos,  size_t len,  const char* s, size_t n);
	//在pos位置长度为len个字符,替换为s字符数组的前n个字符
	string s3("hello world");
	cout << s3 << endl;//hello world
	s3.replace(0, 2, "123456",2);  //12llo world
	cout << s3 << endl;
}
int main()
{
    
    
	test23();
	return 0;
}

insert image description here

string class object non-member function

operator+、operator>>、operator<<、getline、relational operators的使用

operator+ 少用,因为传值返回,导致深拷贝效率低

operator>>、operator<< 分别表示输入运算符重载和输出运算符重载

getline 获取一行字符串,用法为:getline(cin,s) 输入的字符串放在s内

relational operators 即比较大小,字符串可以比较大小,是根据每一字符的Ascil码值

int main()
{
    
    
    string s;
    cin>>s;  //这样读取字符串,读取到' '的时候就会截止
    getline(cin,s); //这样除非遇到'\n' 反之不会停止读取,遇到' '也会继续读取,所以可以读取一行 
    cout<<s<<endl;
    return 0;
}

Summarize

  1. The string class corresponds to the char* character array in the C language. For the convenience of operation, the string class provided in C++
  2. To use the various functions of string, you only need to remember some commonly used ones. For example: append, push_back, +=, find, substr, reserve, resize, empty, clear, c_str, insert, erase, etc.
  3. As long as the function involves the range, it is closed before opening and then opened. It is enough to master the use of string. The expansion mechanism is related to the version environment.

Guess you like

Origin blog.csdn.net/qq_63319459/article/details/131905988