了解string类

string

了解string

  1. string是一个表示字符序列的类

  2. string类是basic_string模板类的一个实例,它使用char来实例化basic_string模板类。

  3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char> string;

  1. string类管理动态增长的字符数组,这个字符串以\0结尾,数组存储在堆区

string类对象的常见构造

函数名称功能说明
string()构造空的string类对象,即空字符串
string(const char s)*用C字符串来构造string类对象
string(size_t n,char c)string类对象中包含n个字符c
string(const string& s)拷贝构造函数
string (const string& str, size_t pos, size_t len = npos)拷贝str的下标为pos的位置开始,len个字符构造
string (const char s, size_t n)*构造函数,C字符串的前n个字符
void test1()
{
	char a[10] = "qwer";
	string s1;		//构造空的string类对象s1
	string s2(a);	//用C格式字符串构造string类对象s2
	string s3("hello world");//用常量字符串构造string类对象s3
	string s4(s2);	//拷贝构造s4
	string s5(5, 'x');//构造string类对象中包含n个字符c
       string s6(s3,6,3);//拷贝s3的下标为6的位置开始,三个字符构造s6
    	string s7(s3,6,100);//超过长度,有多少取多少
    	string s8(s3,6);//取npos个字符,static const size_t npos = -1;
    	string s9("1234567890",4);//构造s9,C字符串的前四个字符
}

注意:

  1. **string (const string& str, size_t pos, size_t len = npos)是半缺省,static const size_t npos = -1,如果len**超过长度,有多少取多少

string类赋值重载函数

string s1("hello");
string s2("xxx");
s1=s2;			//string类可以赋值
s1="qwer";		//C字符串可以赋值
s1='q';			//单个字符可以赋值

string类对象的容量操作

函数名称功能说明
size返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty检测字符串释放为空串,是返回true,否则返回false
clear清空有效字符
reserve为字符串预留空间(改变容量)
resize将有效字符的个数改成n个,多出的空间用字符c填充(会初始化('\0’或指定字符)+改变容量)
void test()
{
    string s1("hello world");
	cout << s1 << endl;
	cout << "capacity:" << s1.capacity() << endl;
	cout << "size:" << s1.size() << endl;
	cout << "lenth:" << s1.length() << endl;

	s1.resize(40, 'x');
	cout << "after resize capacity:" << s1.capacity() << endl;
	cout << "after resize size:" << s1.size() << endl;

	s1.reserve(50);
	cout << "after reserve capacity:" << s1.capacity() << endl;
	cout << "after reserve size:" << s1.size() << endl;

	s1.clear();
	cout << "empty:" << s1.empty() << endl;
	cout << "after clear capacity:" << s1.capacity() << endl;
	cout << "after clear size:" << s1.size() << endl;
}

注意:

  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不会改变容量大小。

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

string类对象的遍历共有三种方式

  1. 下标 + []

    operator[]

    for(size_t i=0;i<s1.size();i++)
    {	//s1.operator[](i)
        cout<<s1[i]<<"";
    }
    

    operator[]函数讲解

    1char& operator[] (size_t pos);
    2const char& operator[] (size_t pos) const;
    返回值是引用,是为了修改,如果是值返回,返回中间变量,中间变量是具有常属性,不可修改
    
  2. 迭代器

    概念:迭代器是像指针一样的东西,或者就是指针用来访问数据结构的。

    获取迭代器函数

    begin():begin获取一个字符的迭代器

    end():end获取最后一个字符下一个位置的迭代器

    rbegin:rbegin获取最后一个字符的迭代器

    rend:rend获取第一个字符前一个位置的迭代器

    四种迭代器

    1. 正向迭代器(可读可写)

      string s1("Hello World");
      string::iterator it = s1.begin();
      while(it!=s1.end())
      {
          cout<<*it<<" ";
          ++it;
      }
      cout<<endl;
      
    2. 反向迭代器(可读可写)

      string::reverse_iterator rit = s1.rbegin();
      while(rit!=s1.rend())
      {
          cout<<*rit<<" ";
          ++rit;
      }
      cout<<endl;
      
    3. 正向迭代器(只读)

      string::const_iterator it = s1.begin();
      while(it!=s1.end())
      {
          cout<<*it<<" ";
          ++it;
      }
      cout<<endl;
      
    4. 反向迭代器(只读)

      string::const_reverse_iterator rit = s1.begin();
      while(rit!=s1.end())
      {
          cout<<*rit<<" ";
          ++rit;
      }
      cout<<endl;
      
  3. 范围for

    for(auto ch:s1)
    {
        cout<<ch<<" ";
        ++it;
    }
    cout<<endl;
    

补充:

[]
越界:断言处理
at
越界:抛异常处理

string类对象的修改操作

函数名称功能说明
push_back在字符串后尾插字符c(插入数据,如果容量不够,会扩容(大概1.5倍))
append在字符串后追加一个字符串
operator+=(最常用)在字符串后追加字符串str
c_str返回C格式字符串(返回指向str指针)
find从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr在str中从pos位置开始,截取n个字符,然后将其返回

函数声明:

//push_back
void push_back (char c);
//c_str
const char* c_str() const;
//find
size_t find (const string& str, size_t pos = 0) const;	
size_t find (const char* s, size_t pos = 0) const;
size_t find (char c, size_t pos = 0) const;
//rfind
size_t rfind (const string& str, size_t pos = npos) const;
size_t rfind (const char* s, size_t pos = npos) const;
size_t rfind (char c, size_t pos = npos) const;
//substr
string substr (size_t pos = 0, size_t len = npos) const;
void Teststring()
{
    string str;
    str.push_back(' '); // 在str后插入空格
    str.append("hello"); // 在str后追加一个字符"hello"
    str += 'w'; // 在str后追加一个字符'b' 
    str += "orld"; // 在str后追加一个字符串"it"
    cout << str << endl;
    cout << str.c_str() << endl; // 以C语言的方式打印字符串

    // 获取file的后缀
    string file1("string.cpp");
    size_t pos = file1.rfind('.');
    string suffix(file1.substr(pos, file1.size() - pos));
    cout << suffix << endl;

    // npos是string里面的一个静态成员变量
    // static const size_t npos = -1;
}

提取url中的协议 域名 uri

	string url1("http://www.cplusplus.com/reference/string/string/find/");
	string& url = url1;

	// 取出url中的协议
	string protocol;
	size_t pos1 = url.find("://");
	if (pos1 != string::npos)
	{
		protocol = url.substr(0, pos1);
		cout << "protocol:" << protocol << endl;
	}
	else
	{
		cout << "非法url" << endl;
	}

	// 取出url中的域名
	string domain;
	size_t pos2 = url.find('/', pos1 + 3);
	if (pos2 != string::npos)
	{
		domain = url.substr(pos1 + 3, pos2 - (pos1 + 3));
		cout << "domain:" << domain << endl;
	}
	else
	{
		cout << "非法url" << endl;
	}

	// 取出url中的uri
	string uri = url.substr(pos2 + 1);
	cout << "uri:" << uri << endl;

insert

函数声明:

string& insert (size_t pos, size_t n, char c);
iterator insert (iterator p, char c);
void test()
{
   string s("hello world");
s.insert(0, 1, 'x');
cout << s << endl;
s.insert(s.begin(), 'y');
cout << s << endl;
s.insert(3, 1, 'x');
cout << s << endl;
s.insert(s.begin() + 3, 'y');
cout << s << endl;
}

erase

函数声明:

string& erase (size_t pos = 0, size_t len = npos);
iterator erase (iterator p);
void test()
{
    string s("hello world");
	s.erase(s.begin());
	cout << s << endl;

	string s1("hello world");
	s1.erase(s1.begin() + 3);
	cout << s1 << endl;

	string s2("hello world");
	s2.erase(3, 2);
	cout << s2 << endl;
	
	string s3("hello world");
	s3.erase(3);
	cout << s3 << endl;
	//lenth缺省值(-1),删完
}

swap(string类内)

函数声明:

void swap (string& str);
void test()
{
    string s1("hello world");
	string s2("string");

	s1.swap(s1);//效率高(交换指针)
	swap(s1,s2);//效率低(深拷贝)
}

注意:

string类内的swap函数是通过交换动态数组的指针,实现交换**(效率高)**

std::swap函数是通过深拷贝实现交换**(效率低)**

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值