【C++】STL——string

前言

string作为我们最先了解的stl,我们需要很深入很全面的学习,方便以后学习其他的stl。

typedef basic_string<char> string;首先我们看到string是一个类模板,经过封装之后呈现出来的。

学习string我们要从使用string类、理解string类、模拟实现string类的底层。

string类的使用

1.string类对象的常见构造

 接下来是对这些常见构造的代码使用。

#include<string>
#include<iostream>
using namespace std;
int main()
{
	//string() (重点),小括号可以省略
	string s1();
	//string(const char* s) (重点)
	string s2("abcd");
	//string(const string&s) (重点) ,拷贝构造
	string s3(s2);
	return 0;
}

2. string类对象的容量操作

   1.size(返回字符串的有效字符长度)

#include<string>
#include<iostream>
using namespace std;
int main()
{
	string s1 = "asdfd";
    //string::size()与string::length()作用相同,但是后面的stl均用string::size(),所以 string::length()不作为重点。
	cout << s1.size() << endl;//5
	cout << s1.length() << endl;//5
	return 0;
}

2.empty(检测字符串释放为空串,是返回true,否则返回false)

#include<string>
#include<iostream>
using namespace std;
int main()
{
	string s1 = "asdfd";
	cout << s1.empty() << endl;//0
	string s2;
	cout << s2.empty() << endl;//1
	return 0;
}

3.clear(清空有效字符)

#include<string>
#include<iostream>
using namespace std;
int main()
{
	string s1 = "asdfd";
	cout << s1.empty() << endl;//0
	s1.clear();
	cout << s1.empty() << endl;//1
	return 0;
}

4.string的扩容(reserve和resize)

#include<string>
#include<iostream>
using namespace std;
void TestPushBack()
{
	string s;
	size_t sz = s.capacity();
	cout << "capacity changed: " << sz << '\n';
	cout << "making s grow:\n";
	for (int i = 0; i < 100; ++i)
	{
		s.push_back('c');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "capacity changed: " << sz << '\n';
		}
	}
}
int main()
{
	TestPushBack();
	return 0;
}

当有效字符长度小于16时,字符会存入_Buf空间中,大于16时再存入_Ptr空间中。在VS下为1.5倍扩容,然而在linux操作系统下buffer的概念,与顺序表类似为二倍扩容。

测试:string s1("11111111"); string s2("1111111111111111111111111111111111");

int main()
{
	string s1;
	//此时开辟空间位置的数据为默认字符
	s1.resize(5);
	string s2;
	//此时开辟空间位置的数据为字符‘5’
	s2.resize(5, '5');
	return 0;
}

注意:

1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一 致,一般情况下基本都是用size()。

2. clear()只是将string中有效字符清空,不改变底层空间大小。

 3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字 符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的 元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大 小,如果是将元素个数减少,底层空间总大小不变。

4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于 string的底层空间总大小时,reserver不会改变容量大小。 

5.capacity()比实际空间少一个,有一个多的预留给了‘\0’。

6.在VS下默认不缩容

3. string类对象的访问及遍历操作

1.operator[](返回pos位置的字符,const string类对象调用) 

int main()
{
	string s1("11111222");
	for (int i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";//1 1 1 1 1 2 2 2
	}
	cout << endl;
	return 0;
}

2.迭代器(begin+end)

int main()
{
	string s1("11111222");
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << endl;//1 1 1 1 1 2 2 2 
		it++;
	}
	return 0;
}

现阶段可以把迭代器理解为指针。

3.反向迭代器(rbegin+rend)

int main()
{
	string s1("11111222");
	string::reverse_iterator rit = s1.rbegin();
	while (rit != s1.rend())
	{
		cout << *rit << " ";//2 2 2 1 1 1 1 1
		++rit;
	}
	cout << endl;
	return 0;
}

4.范围for(C++11支持更简洁的范围for的新遍历方式)

int main()
{
	string s1("liuzhi66");
	//使用引用会使效率更高,尤其是对于自定义类型
	for (const auto& e : s1)
	{
		cout << e ;//liuzhi66
	}
	cout << endl;
	return 0;
}

4. string类对象的修改操作

1.operator+=(在字符串后追加字符串str)

int main()
{
	string s1("llliiuuzzhi");
	cout << s1 << endl;//llliiuuzzhi
	s1 += "sdafsd";
	cout << s1 << endl;//llliiuuzzhisdafsd
	return 0;
}

2.c_str(返回C格式字符串)

// strings and c-strings
#include <iostream>
#include <cstring>
#include <string>

int main ()
{
  std::string str ("Please split this sentence into tokens");

  char * cstr = new char [str.length()+1];
  std::strcpy (cstr, str.c_str());

  // cstr now contains a c-string copy of str

  char * p = std::strtok (cstr," ");
  while (p!=0)
  {
    std::cout << p << '\n';
    p = std::strtok(NULL," ");
  }

  delete[] cstr;
  return 0;
}

3.find(从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置) 

// string::find
#include <iostream>       // std::cout
#include <string>         // std::string

int main ()
{
  std::string str ("There are two needles in this haystack with needles.");
  std::string str2 ("needle");

  // different member versions of find in the same order as above:
  std::size_t found = str.find(str2);
  if (found!=std::string::npos)
    std::cout << "first 'needle' found at: " << found << '\n';

  found=str.find("needles are small",found+1,6);
  if (found!=std::string::npos)
    std::cout << "second 'needle' found at: " << found << '\n';

  found=str.find("haystack");
  if (found!=std::string::npos)
    std::cout << "'haystack' also found at: " << found << '\n';

  found=str.find('.');
  if (found!=std::string::npos)
    std::cout << "Period found at: " << found << '\n';

  // let's replace the first needle:
  str.replace(str.find(str2),str2.length(),"preposition");
  std::cout << str << '\n';

  return 0;
}

5.string类非成员函数

  • 5
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值