前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

string

作者头像
code-child
发布2023-05-30 14:25:22
2660
发布2023-05-30 14:25:22
举报
文章被收录于专栏:codechildcodechild

查询这些接口的网址:点击蓝色字体即可进入请点击


string类的常用接口

  • begin

返回字符串第一个字符的迭代器

  • end

返回一个迭代器,该迭代器为字符串最后一个字符的后一个。 通常用beginend形成一个区间来遍历一个字符串。

代码语言:javascript
复制
cpp	string s("ml is cool");
	for (std::string::iterator it = s.begin(); it != s.end(); ++it)
		cout << *it;
	cout << endl;
  • size

返回字符串的长度。

代码语言:javascript
复制
cpp	string s("ml is cool");
	cout << s.size() << endl;

输出的结果为10


  • capacity

获取储存字符串的容量。

代码语言:javascript
复制
cpp	string a("ml is cool");
	cout << a.capacity() << endl;

输出的结果为15

  • npos

公共的静态的全局成员。


  • resize

改变字符串的大小到n,如果n小于size,删除n后面的字符,即在n号位置的字符变成\0,容量不变。如果大于size, 容量改变,比原来字符串多的字符都变成c,如果没有指定给的字符,就用\0进行填充。

代码语言:javascript
复制
cpp	string a("ml is cool");	
	string b("ml is cool");
	string c("ml is cool");
	a.resize(3);
	b.resize(20);
	c.resize(20,'h');
  • reserve

改变容量成n,如果n小于容量(capacity),这是不被允许的。如果n大于capacity,就把容量扩大到n。

  • empty

判断字符串是否为空。


  • find

查找字符或者字符串所在的位置,查找到就返回它们的第一次出现的位置,否则返回npos nops-1-1size_t的时候会变成一个非常大的值。(整型提升)

  • rfind

从字符串pos位置的字符开始向前进行查找,当pos的值为npos或者为size_t()-1 时就是对整个字符串进行查找。第(3)个是从[pos,pos+n)进行查找。

代码语言:javascript
复制
cpp	string str("ml is cool");
	cout << str.find("is") << endl;
	cout << str.rfind('i',5) << endl;
  • find_first_of

find差不多,只不过它是从字符串的pos位置开始向后查找,只要发现和str中的任意一个字符相同,则就返回该字符的位置。

代码语言:javascript
复制
cpp	string s("ml is cool");
	cout << s.find_first_of("abc", 1) << endl;

输出的结果为6。


  • substr

生成新的string对象,子串是从pos的位置向后获取len个字符,即[pos,pos+len)len的类型为无符号的整型size_t,所以当值很大的时候,是到字符串的结尾。当然负数转为size_t的时候也会变的很大。

代码语言:javascript
复制
cpp	string s("ml is cool");
	string str;
	str = s.substr(0,2);
	cout << str << endl;

  • insert

该接口为插入一段字符。14,都是从pos位置开始插入一个字符或者字符串。 57,对于迭代器iterator的参数,需要传迭代器参数。


  • erase

从某个位置开始删除,删除len个字符,对于第2个函数,删除迭代器的位置的字符,第三个函数,表示从迭代器的开始位置删到结束位置。

代码语言:javascript
复制
cpp	string str("ml is cool");
	cout << str << endl;
	str.erase(3, 2);
	cout << str << endl;
  • push_back

在字符串的尾部插入一个字符。

代码语言:javascript
复制
cpp	string a("ml is cool");
	a.push_back('s');
	cout << a << endl;

输出结果:ml is cools

  • append

把字符串追加到原来字符串的结尾。当然不同的函数重载有不同的,追加方式。可以说这个函数不用都可以,毕竟有+=,push_back

代码语言:javascript
复制
cpp	string a("ml is cool");
	string b("nbnbnbnb");
	a.append("hhhhhhhhhh");
	cout << a << endl;
	a.append("###########", 3);
	cout << a << endl;
	a.append(3,'h');
	cout << a << endl;
	a.append(b);
	cout << a << endl;
  • operator+

实现两个字符串的拼接。把后一个字符串连接到前一个字符串上。

代码语言:javascript
复制
cpp	string s1("ml ");
	string s2("is cool");
	string s3;
	s3 = s1 + s2;
	cout << s3 << endl;
  • operator+=

+=运算的重载本质就是在原来字符串的后面加上一组新串,或者字符。

代码语言:javascript
复制
cpp	string a("ml");
	string b(" cool");
	a += ' ';
	cout << a << endl;
	a += "is";
	cout << a << endl;
	a += b;
	cout << a << endl;

看结果:


  • c_str

string类型的字符串,转换成c语言类型的字符串(就是以\0)

代码语言:javascript
复制
cpp	string a("ml is cool");
	a += '\0';
	a += "hhhhhhhhh";
	cout << a.c_str() << endl;

  • clear

清空字符串,字符串长度为0,但容量不变,即不是否开辟的空间。

代码语言:javascript
复制
cpp	string a("ml is cool");
	a.clear();

下面函数不是string类里面的。

  • getline

如何获取一行字符串呢?仅仅靠cin,是不行的。这里提供一个函数getline,它不是在string这个类里面的函数,而是std标准库里面的。 下面看它的使用:

对于(1),第一个参数为输入流(cin从键盘上输入),第二个参数为string对象,而第三个参数为以什么结束的字符。 当没有第三个参数的时候,结束以\n为结束的。

代码语言:javascript
复制
cpp	string str;
	getline(cin, str);
	cout << str << endl;

string类的模拟实现

对于一个string类的实现,它的成员变量主要有:字符的指针,字符串的实际的大小,开辟该字符的容量。

代码语言:javascript
复制
cppchar* _str;
size_t _size;//字符的实际大小
size_t _capacity;//容量

构造函数 对于一个字符串我们怎么初始化呢? 要分为几种情况: 1.用户没有传入任何字符 2.用户传入字符串

为了解决上述的情况,我们可以提供全缺省的构造函数。 缺省参数为"",空字符串,里面只包含\0_size大小为传入参数字符串的长度 _capacity的大小就是_size的大小,当然,也可以开一定的空间。 _str开的空间要比_size要大一个,因为要储存\0

代码语言:javascript
复制
cpp		string(const char* str = "")
		{
			_size = strlen(str);
			_str = new char[_size + 1];
			_capacity = _size;
			strcpy(_str, str);
		}

拷贝构造 注意要深拷贝,不能直接把str._str的地址给_str,如果这样会使析构两次,非法释放空间。

代码语言:javascript
复制
cpp		string(const string& str)
		{
			_size = str._size;
			_capacity = str._capacity;
			_str = new char[_size + 1];
			strcpy(_str, str._str);
		}

析构函数 释放开辟的空间,大小和容量归0

代码语言:javascript
复制
cpp		~string()
		{
			delete[] _str;
			_str = nullptr;
			_size = _capacity = 0;
		}

赋值运算符重载 主要注意的是,要把原来_str指向的字符串释放(判断给自己赋值这种情况),然后重新开辟一段空间,然后赋值过去。

代码语言:javascript
复制
cpp		string& operator=(const string& str)
		{
			if (_str == str._str)
				return *this;
			delete[] _str;
			_size = str._size;
			_capacity = str._capacity;
			_str = new char[_size + 1];
			strcpy(_str, str._str);
			return *this;
		}

+=运算符重载 这里实现两种+=,一种是+=一个字符,另一种是+=字符串 在+=的时候要判断容量(需要有扩容的处理)

代码语言:javascript
复制
cpp		string& operator+=(const char ch)
		{
			if (_size == _capacity)
			{
				size_t n= _capacity == 0 ? 4 : _capacity * 2;
				reserve(n);
			}
			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
			return *this;
		}
		string& operator+=(const char* str)
		{
			size_t len = strlen(str);
			if (_size + len >= _capacity)
			{
				size_t n = _capacity == 0 ? len  : (_size + len) * 2;
				reserve(n);
			}
			strcpy(_str + _size, str);
			_size += len;
			return *this;
		}

npos 静态的不可修改的公共成员 static const size_t npos = -1;


查看字符串的长度

代码语言:javascript
复制
cpp		size_t size()const
		{
			return _size;
		}

查看储存字符串的容量

代码语言:javascript
复制
cpp		size_t capacity()const
		{
			return _capacity;
		}

查看字符串是否为空

代码语言:javascript
复制
cpp		bool empty()const
		{
			return _size;
		}

清空字符串 只把字符串变成空串,容量不变。

代码语言:javascript
复制
cpp		void clear()
		{
			_size = 0;
			_str[_size] = '\0';
		}

[]操作符的重载 要判断一下pos的位置是否正确。

代码语言:javascript
复制
cpp		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}
		const char& operator[](size_t pos)const
		{
			assert(pos < _size);
			return _str[pos];
		}

改变容量的大小 当n小于_capacity不做处理,当n大于它时扩充容量。注意数据的保存。

代码语言:javascript
复制
cpp		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				_capacity = n;
				char* temp = new char[_capacity+1];
				strcpy(temp, _str);
				delete[] _str;
				_str = temp;
			}
		}

改变字符串的长度

代码语言:javascript
复制
cpp		void resize(size_t n, char ch='\0')
		{
			if (n <= _size)
			{
				_str[n] = '\0';
				_size = n;
			}
			else
			{
				reserve(n);
				memset(_str + _size, ch, n - _size);
				_size = n;
			}
		}

尾插 在字符串的最后插入一个字符。要注意空间的容量是否够用。不够用的话就需要扩容。这里我就复用我之前写的+=运算符的重载。(还是偷懒舒服)

代码语言:javascript
复制
cpp		string& push_back(char ch)
		{
			*this += ch;
			return *this;
		}

append模拟实现 这里只模拟插入一个字符串,我们会发现这不就是**+=**的实现嘛。

代码语言:javascript
复制
cpp		string& append(const char* str)
		{
			size_t len = strlen(str);
			if (_size + len == _capacity)
			{
				size_t n = _capacity == 0 ? len : (_size + len) * 2;
				reserve(n);//该函数已经把_capacity的值扩充到了n
			}
			strcpy(_str + _size, str);
			return *this;
		}

c_str,转换成c语言样式的字符串,注意只是只读,所以用const。

代码语言:javascript
复制
cpp		const char* c_str()const
		{
			return _str;
		}

查找 从某个位置开始进行查找字符串或者查找某个字符,返回第一个匹配的位置的下标,对于查找的位置要注意是否合法,当然对于查找字符串的时候,用strstr查找到的时候会返回匹配的字符串的首个字符的地址。对于它的位置,我们用指针相减即可获得该匹配的位置。

代码语言:javascript
复制
cpp		size_t find(char ch, size_t pos)const
		{
			assert(pos < _size);
			for (size_t i = pos; i < _size; ++i)
			{
				if (_str[i] == ch)
					return i;
			}
			return npos;
		}
		size_t find(const char* str, size_t pos)const
		{
			assert(pos < _size);
			char* p = strstr(_str+pos, str);
			if (p == nullptr)
				return npos;
			else
			{
				return p - _str;
			}
		}

任意位置插入字符或者字符串 判断插入的位置是否正确,是否需要扩容。

代码语言:javascript
复制
cpp		string& insert(size_t pos, char ch)
		{
			assert(pos < _size);
			if (_size == _capacity)
			{
				reserve(_capacity + 1);
			}
			size_t p = _size;
			while (p > pos)
			{
				_str[p] = _str[p - 1];
				--p;
			}
				
			//strcpy(_str + pos + 1, _str + pos);
			_str[pos] = ch;
			++_size;
			_str[_size] = '\0';
			return *this;
		}
		string& insert(size_t pos, const char* str)
		{
			assert(pos <= _size);
			size_t len = strlen(str);
			if (_size + len >= _capacity)
			{
				size_t newlen = _capacity == 0 ? len : (_size + len) * 2;
				reserve(newlen);
			}
			size_t p = _size;
			while (p >= pos)//注意边界问题
			{
				_str[p + len] = _str[p];
				--p;
			}
			strncpy(_str + pos, str,len);//不能用strcpy因为会拷贝\0。
			_size += len;
			_str[_size] = '\0';
			return *this;
		}

删除某个位置的字符 首先要判断删除位置是否合法,删除之后要修改size的大小。删除的时候我们从后往前覆盖。

代码语言:javascript
复制
cpp		string& erase(size_t pos = 0, size_t len = npos)
		{
			assert(pos < _size);
			if (len == npos || len >= _size - pos)
			{
				_size = pos;
				_str[_size] = '\0';
				return *this;
			}
			strcpy(_str + pos, _str + len);
			return *this;
		}

首字符,末字符的迭代器 string类的迭代器其实就是指针。

代码语言:javascript
复制
cpp		typedef char* iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}

流插入,流提取重载

代码语言:javascript
复制
cpp	ostream& operator<<(ostream& os, const string& str)
	{
		for (size_t i = 0; i < str.size(); ++i)
		{
			os << str[i];
		}
		return os;
	}
	istream& operator>>(istream& oi, string& str)
	{
		char ch;
		ch = oi.get();
		while (ch != ' ' && ch != '\n')
		{
			str += ch;
			ch = oi.get();
		}
		str += '\0';
		return oi;
	}

这里的流插入用到了get

该函数是为了获得一个字符。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2023-05-26c,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • string类的常用接口
  • string类的模拟实现
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档