【C++】string类的使用


目录

一、string

1、string的介绍

2、为什么string类要实现为模板?

二、元素访问

1、使用operator[]实现数组下标式的访问

2、迭代器读写

2.1正向迭代器

2.2反向迭代器

2.3const正向迭代器(不能改变*it)

2.4const反向迭代器(不能改变*it)

3、范围for读写

三、string的构造接口

四、string的容量相关的接口

1.reserve(调整容量)

2.resize(调整size)

五、string对象修改相关的接口

1、insert

2、earse

3、assign

4、replace

六、string对象字符串运算相关接口

1、c_str

2、find查找+substr返回子串

七、部分非成员函数接口

1、getline

八、string对象与其他类型互相转换

1、stoi等

2、to_string


一、string

1、string的介绍

string是管理字符数组的类。

typedef basic_string<char> string;

basic_string是模板。将basic_string<char>这个实例重命名为string。

2、为什么string类要实现为模板?

我们印象中,单个字符就是1个字节,也就是char类型,但是由于编码问题,会有2字节和4字节的字符类型。

类型

编码

类型

string

UTF-8

char

wstring

Unicode

wchar_t

u16string

UTF-16

char16_t

u32string

UTF-32

char32_t

对于字符串的多种类型,设计了basic_string模板。

二、元素访问

1、使用operator[]实现数组下标式的访问

int main()
{
	string s("hello world");//构造
	for (size_t i = 0; i < s.size(); ++i)//读
	{
		cout << s[i] << " ";//等价于cout << s.operator[](i) << " ";
	}
	cout<<endl;
	for (size_t i = 0; i < s.size(); ++i)//写
	{
		cout << (s[i] += 1) << " ";
	}
	return 0;
}

operator[]和at的区别在于operator[]是断言,at是抛异常。主要release版本assert失效。

2、迭代器读写

2.1正向迭代器

int main()
{
	string s("hello world");
	string::iterator it = s.begin();
	//遍历访问
	while (it != s.end())
	{
		cout << *it;
		++it;
	}
	cout << endl;
	it = s.begin();//将it重新置为s.begin位置
	//遍历修改
	while (it != s.end())
	{
		*it += 1;
		cout << *it;
		++it;
	}
	return 0;
}

2.2反向迭代器

int main()
{
	string s("hello world");
	string::reverse_iterator rit = s.rbegin();
	//遍历访问
	while (rit != s.rend())
	{
		cout << *rit;
		++rit;
	}
	cout << endl;
	//遍历修改
	rit = s.rbegin();//将rit重新置为s.rbegin位置
	while (rit != s.rend())
	{
		*rit += 1;
		cout << *rit;
		++rit;
	}
	return 0;
}

2.3const正向迭代器(不能改变*it)

void test(const string& s)
{
	string::const_iterator it = s.begin();
	while (it != s.end())
	{
		cout << *it;
		++it;
	}
}

2.4const反向迭代器(不能改变*it)

void test(const string& s)
{
	string::const_reverse_iterator rit = s.rbegin();
	while (rit != s.rend())
	{
		cout << *rit;
		++rit;
	}
}

3、范围for读写

int main()
{
	string s("hello world");
	//范围for的遍历访问
	for (auto e : s)
	{
		cout << e;
	}
	cout << endl;
	//范围for的遍历修改
	for (auto& e : s)
	{
		e += 1;
		cout << e;
	}
	return 0;
}

三、string的构造接口

函数名称

功能说明

string() (重点)

无参的构造,构造空字符串

string(const char* s) (重点)

用C_string字符串构造对象

string(size_t n, char c)

用n个字符创建对象

string(const string& s) (重点)

拷贝构造

string (const string& str, size_t pos, size_t len = npos)

用对象构造,下标为2至len位置

string (const char* s, size_t n)

用字符串的前n个构造对象

template <class InputIterator>

string (InputIterator first, InputIterator last);

迭代器区间构造

int main()
{
    string s1;//无参的构造      
    string s2("hello world");//用C_string字符串构造对象    
    string s3(3, 'x');//用3个字符创建对象
    string s4(s2);//拷贝构造
    string s5(s2, 2, 7);//用s2对象构造,下标为2开始,共7个字符构造s5,结果为llo wor
    string s6("hello world", 7);//用字符串构前7个字符构造
    string s7(s2.begin(),s2.begin()+3);//迭代器区间构造
    return 0;
}

四、string的容量相关的接口

函数名称

功能说明

size(重点)

返回字符串的长度,不包含'\0'

length

返回字符串的长度,不包含'\0'

capacity

返回数组容量

empty(重点)

字符串的判空

clear(重点)

将size置为0,不改变容量

reserve(重点)

用于预先开好空间

resize(重点)

调整size的大小,可能会改变容量。多出来的位置用'\0'填充

1.reserve(调整容量)

reserve用于预先开好空间,如果预开空间小于现有空间,将不会改变容量。

2.resize(调整size)

int main()
{
	string s("hello world");
	s.resize(20, 'x');//将size改为20,多出来的位置用字符x填充
	s.resize(30);//将size改为30,多出来的位置用'\0'填充
	return 0;
}

reserve和resize扩容时不会对已有的数据做改变,但缩容时会放弃超出空间的已有数据。

五、string对象修改相关的接口

函数名称

功能说明

push_back

尾插一个字符

append

尾插字符串

operator+=(重点)

字符、字符串尾插

insert

在pos位置插入

earse

在pos位置删除

assign

对原有字符串清空后赋值

replace

替换

1、insert

string& insert (size_t pos, const string& str);//pos位置插入string对象
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);//pos位置插入字符对象的一部分
string& insert (size_t pos, const char* s);//pos位置插入字符串
string& insert (size_t pos, const char* s, size_t n);//pos位置插入字符串的前n个
string& insert (size_t pos, size_t n, char c);//在pos位置插入n个字符
void insert (iterator p, size_t n, char c);
iterator insert (iterator p, char c);

template <class InputIterator>
void insert (iterator p, InputIterator first, InputIterator last);

2、earse

string& erase (size_t pos = 0, size_t len = npos); //从pos位置删除len个字符
iterator erase (iterator p);
iterator erase (iterator first, iterator last);

3、assign

assign可以理解成将原字符对象清空,重新进行赋值操作。

4、replace

repalce是对字符对象的部分取代。

#include <iostream>
#include <string>
#include <cstddef>

int main ()
{
  std::string str ("The sixth sick sheik's sixth sheep's sick.");
  std::string key ("sixth");

  std::size_t found = str.rfind(key);
  if (found!=std::string::npos)
    str.replace (found,key.length(),"seventh");

  std::cout << str << '\n';

  return 0;
}

六、string对象字符串运算相关接口

c_str(重点)

将string对象返回c格式字符串的指针

find(重点)

查找

rfind

倒着找

substr(重点)

返回子串

find_first_of

返回第一个匹配字符的下标

1、c_str

int main()
{
	string s("hello world");
	//虽然打印结果一样,但c_str()返回const char*,可以用于返回值有要求的地方
	cout << s << endl;
	cout << s.c_str() << endl;

	string file("test.txt");
	FILE* fout = fopen(file.c_str(), "w");
	return 0;
}

2、find查找+substr返回子串

size_t find (const string& str, size_t pos = 0) const;//从pos位置开始,在string对象中找str
size_t find (const char* s, size_t pos = 0) const;//从pos位置开始,在string对象中找s
size_t find (const char* s, size_t pos, size_t n) const;//从pos位置开始,在string对象中匹配s的前n个
size_t find (char c, size_t pos = 0) const;//从pos位置开始,在string对象中找字符

rfind是找到字符最后一次出现位置的下标。

一闭一开才是真实距离!!!

查找.后边的内容:

int main()
{
	string file("test.txt");
	size_t pos = file.find('.');//size_t find (char c, size_t pos = 0) const;
	if (pos != string::npos)//npos是定义在string中的静态变量
	{
		string suffix = file.substr(pos,file.size()-pos);//这里长度不给也行,默认是npos
		cout << suffix << endl;
	}
	return 0;
}

查找协议:

int main()
{
	string url("https://legacy.cplusplus.com/reference/string/string/find/");
	size_t pos = url.find(':');
	if (pos != string::npos)
	{
		string protocol = url.substr(0, pos);//从0开始数pos个元素
		cout << protocol << endl;
	}
	return 0;
}

查找域名:

int main()
{
	string url("https://legacy.cplusplus.com/reference/string/string/find/");
	size_t pos1 = url.find(':');
	size_t pos2 = url.find('/', pos1 + 3);
	if (pos2 != string::npos)
	{
		string domainName = url.substr(pos1+3, pos2-pos1-3);
		cout << domainName << endl;
	}
	return 0;
}

查找地址:

int main()
{
	string url("https://legacy.cplusplus.com/reference/string/string/find/");
	size_t pos1 = url.find(':');
	size_t pos2 = url.find('/', pos1 + 3);
	string uri = url.substr(pos2+1);
	cout << uri << endl;
	return 0;
}

七、部分非成员函数接口

函数名称

功能说明

operator+

左右操作数必须有一个string对象或

operator<<

流插入

operator>>

流提取

getline(重点)

获取一行

流提取是不能接收到空格和换行的,需要接收一行的时候需要使用getline。 

1、getline

istream& getline (istream& is, string& str, char delim);//从流提取中取出字符至str中,直至遇到delim或'\n'
istream& getline (istream& is, string& str);//从流提取中取出字符至str中
getline(std::cin,str);

八、string对象与其他类型互相转换

1、stoi等

 将一个string对象转化为int类型的数字。

idx如果不传或者为nullptr,则表示不使用这个参数;反之,&idx指向string对象数字字符的后一个位置。

2、to_string

能够把内置类型转化为string对象。

猜你喜欢

转载自blog.csdn.net/gfdxx/article/details/127760886