面向对象程序设计(C++)之 String 类

1. String 构造函数

String 可以理解为一个字符数组,在创建 String 类型变量的时候可以使用很多形式,因为 String 有很多实用的构造函数

首先使用String类要包含头文件 #include<string>

接下来使用代码依次演示上述构造函数的用法: 

#include<iostream>
#include<string>
using namespace std;

int main()
{
	//1. 空构造,没有什么实际参数
	string s1;

	//2. 初始化构造,在创建的同时初始化
	string s2("man what can i say");
	cout << "s2 = " << s2 << endl;//man what can i say

	//3.拷贝构造,将构造好的拷贝(深拷贝)给新的String类
	string s3 = s2;
	cout << "s3 = " << s3 << endl;//man what can i say

	//4.按照指定长度拷贝,根据开始位置与拷贝长度指定拷贝字符串
	string s4(s2, 2, 4);//拷贝 s2 的从第二个字符开始总计4长度的字符串(包含空格)
	cout << "s4 = " << s4 << endl;//n wh

	//5. 拷贝指定字符串的指定长度字符串(从头开始拷贝)
	string s5("man what can i say", 5);
	cout << "s5 = " << s5 << endl;//man w

	//6. 初始化指定长度的单一字符
	string s6(10, 'X');
	cout << "s6 = " << s6 << endl;//XXXXXXXXXX

	//7.依据下标对指定字符修改
	s2[0] = 'x';
	cout << "s2 = " << s2 << endl;//xan what can i say

	return 0;
}

2. String 的遍历

2.1 下标遍历

类似于数组遍历, 依据下标依次遍历,不过需要使用 String 类自带的 string::size 函数确定范围

#include<iostream>
#include<string>
using namespace std;

//string 的遍历
int main()
{
	string s1("byte");

	//1.下标遍历,size函数返回长度
	for (size_t i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << " ";
	}
	cout << endl;

	return 0;
}

2.2 迭代器遍历

使用名为迭代器的容器遍历,具体可以自行了解(了解迭代器 iterator 点这里) 


 2.2.1 正向迭代器(正向遍历)

#include<iostream>
#include<string>
using namespace std;

//string 的遍历
int main()
{
    string s1("byte");
	//2.迭代器遍历,begin指向起始位置,end指向结尾
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;

	return 0;
}

2.2.2 反向迭代器(反向遍历)

#include<iostream>
#include<string>
using namespace std;
int main()
{
	string s1("byte");
	string::reverse_iterator rit = s1.rbegin();
	while (rit != s1.rend())
	{
		cout << *rit << " ";
		rit++;
	}
	cout << endl;
	return 0;
}

2.2.3 const 正向迭代器

const 迭代器指向内容不可以修改,本身可以修改,相当于 const 在*左边

#include<iostream>
#include<string>
using namespace std;
int main()
{
	const string s1("byte");
	string::const_iterator cit = s1.begin();
	while (cit != s1.end())
	{
		cout << *cit << " ";
		cit++;
	}
	cout << endl;
	return 0;
}

2.2.4 const 反向迭代器

#include<iostream>
#include<string>
using namespace std;
int main()
{
	const string s1("byte");

	string::const_reverse_iterator crit = s1.rbegin();
	while (crit != s1.rend())
	{
		cout << *crit << " ";
		crit++;
	}
	cout << endl;

	return 0;
}

2.3 范围 for 遍历

范围for(range-based for loop)是C++11新引入的特性,可遍历各种序列结构的容器(如数组、vector、list等)每次循环都会将序列中的下一个元素,赋值给声明的变量,直到循环结束 

//element_declaration 声明循环变量的类型和名字
//sequence 是一个序列结构,例如数组、向量、列表等,或具有迭代器接口的对象;
for ( element_declaration : sequence ) {
    // 循环体
}
#include<iostream>
#include<string>
using namespace std;

//string 的遍历
int main()
{
	string s1("byte");
	//3. 范围for遍历,auto表示自动推导类型,自动赋值,自动迭代,自动判断结束
    //   要修改则使用引用修改需要遍历的元素
	for (auto& ch : s1)
	{
		ch += 2;
	}
	cout << endl;

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

	return 0;
}

3. String 的一些常用库函数 

3.1 string::size

计算字符串长度

#include<iostream>
#include<string>
using namespace std;
//常用库函数
int main()
{
	string s("manbo");
	//size 函数
	cout << s.size() << endl;//5

	return 0;
}

3.2 string::max_size

计算字符串最大可输入长度 

#include<iostream>
#include<string>
using namespace std;
//常用库函数
int main()
{
	string s("manbo");
	//size 函数
	cout << s.size() << endl;//5

	//max_size 函数
	cout << s.max_size() << endl;//9223372036854775807

	return 0;
}

 3.3 string::capacity

计算 string 的容量

在 VS 下,扩容第一次二倍扩容,之后为1.5 倍扩容,而在 linux 操作系统下均为二倍扩容

其原因是 VS 做了特殊处理,在小于16字节的情况会将字符存入一个 _Buf 数组(栈上存储),而大于16则会存入 _Ptr 数组(堆上存储),不再使用 _Buf 数组。

并且 string 不包含'\0',因为容量的定义是存入字符的个数,所以通常在所得容量上 +1就是真正的容量

#include<iostream>
#include<string>
using namespace std;
//常用库函数
void Capacity_Grow()
{
	string s;
	size_t sz = s.capacity();
	cout << "capacity change: " << sz << endl;
	cout << "make s grow" << endl;
	for (int i = 0; i < 100; i++)
	{
		s.push_back('c');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "capacity change: " << sz << endl;
		}
	}

}
int main()
{
	string s("manbo");
	//capacity 函数
	Capacity_Grow();

	return 0;
}

3.4 string::reserve 

提前申请一定空间,减少扩容次数

需要注意的是,当给出的数字小于原容量时,在VS环境下不会缩减,在gcc环境下则会缩减

#include<iostream>
#include<string>
using namespace std;
//常用库函数
void Capacity_Grow()
{
	string s;
	s.reserve(100);//提前保留100字节空间
	size_t sz = s.capacity();
	cout << "capacity change: " << sz << endl;
	cout << "make s grow" << endl;
	for (int i = 0; i < 100; i++)
	{
		s.push_back('c');
		if (sz != s.capacity())
		{
			sz = s.capacity();
			cout << "capacity change: " << sz << endl;
		}
	}

}
int main()
{
	string s("manbo");
	//size 函数
	//cout << s.size() << endl;//5

	//max_size 函数
	//cout << s.max_size() << endl;//9223372036854775807

	//capacity 函数
	Capacity_Grow();

	return 0;
}

 3.5 string::clear

清除数据,但不减少容量(减少size,不改变capacity)

int main()
{
	string s("manbo");
	//clear 函数
	cout << "not reserve" << endl;
	cout << "s.size() = " << s.size() << endl;
	cout << "s.capacity() = " << s.capacity() << endl;
	s.reserve(100);
	s.clear();
	cout << "reserve" << endl;
	cout << "s.size() = " << s.size() << endl;
	cout << "s.capacity() = " << s.capacity() << endl;

	return 0;
}

3.6 string::empty

判断是否为空,非零为空,零为非空

int main()
{
	string s("manbo");
	
	//empty 函数
	cout << "s.size() = " << s.size() << endl;
	cout << "s.capacity() = " << s.capacity() << endl;
	cout << s.empty() << endl;

	return 0;
}

3.7 string::push_back

对字符串进行尾插操作,只能插入单个字符

int main()
{
	
	//push_back 函数
	string s("manb");
	s.push_back('o');
	cout << "s : " << s << endl;


	return 0;
}

3.8 string::append 

与 string::push_back 功能相似但是更加多样,可以插入字符串

int main()
{
      //append 函数
      string s("manbo ");
      s.append(" manbo ");
      cout << "s :" << s << endl;
     
      return 0;
}

3.9 string::operator+=

使用 += 可以直接在字符串后添加需要的元素 

int main()
{
	//operator+=
	string s;
	s += "manbo";
	cout << "s : " << s << endl;

	return 0;
}

3.10 string::insert

在指定位置进行插入字符或者字符串

int main()
{
	//insert 函数
	string s("manbo");
	s.insert(0, "hello");//在第0个位置的添加字符串
	cout << "s : " << s << endl;

	char ch = 'x';
	s.insert(0, 1, ch);//在第起始位置仅插入一个字符
	cout << "s : " << s << endl;
	s.insert(s.begin(),ch);//迭代器
	cout << "s : " << s << endl;
	return 0;

	return 0;
}

3.11 string::erase 

对指定位置删除指定字符或者字符串

int main()
{
	//erase 函数
	string s("manbo");
	cout << "s : " << s << endl;
	//头删
	s.erase(0, 1);
	cout << "s : " << s << endl;
	s.erase(s.begin());
	cout << "s : " << s << endl;
	
	//尾删
	s.erase(--s.end());
	cout << "s : " << s << endl;
	s.erase(s.size() - 1, 1);
	cout << "s : " << s << endl;

    string ss("manbo manbo");
    ss.erase(6);//删除指定位置之后的所有字符
    cout << "ss : " << ss << endl;

	return 0;
}

3.12 string::replace

替换指定位置字符或者字符串

int main()
{
	//replace 函数
	string s("hello    manbo");
	cout << "s : " << s << endl;
	s.replace(0, 1, "%%");
	cout << "s : " << s << endl;

	return 0;
}

3.13 string::find 

查找指定位置的指定字符或字符串,返回值类型为 size_t,找到则返回第一个目标下标,否则返回 string::npos 的数值

int main()
{
	//find 函数
	string ss("hello    manbo");
	cout << "ss : " << ss << endl;
	size_t pos = ss.find(' ');//查找空格
	cout << "pos = " << pos << endl;

	return 0;
}

3.13 string::getline

获取I/O流数据并可以自己定义终止条件,不定义则默认换行为终止条件

这里借助试题 最后一个单词的长度 练习

int main()
{
	//getline 函数
	string str;
	getline(cin, str, '%');
	size_t pos = str.rfind(' ');
	cout << str.size() - (pos + 1) << endl;

	return 0;
}

  • 23
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值