您的当前位置:首页正文

C++——String类讲解

2024-11-28 来源:个人技术集锦

一. 为什么学习string类?

    C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列 的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户 自己管理,稍不留神可能还会越界访问。

二. 标准库中的string类

  1. string类对象的常见构造

#include<iostream>
#include<string>
using namespace std;
int main()
{
	//直接创造一个对象
	string a;        
	cout << a << endl;

	//直接构造
	string b("hello world");
	cout << b << endl;

	//首地址来构造
	char arr[] = {"abcd"};
	string c(arr);
	cout << c << endl;

	//拷贝构造
	string d(b);
	string e = b;
	cout << d << endl;

	//将前n个初始化
	string f(5, 'x');
	cout << f << endl;
}

2. string类对象的容量操作 

 

#include<iostream>
#include<string>
using namespace std;
int main()
{
	string a("hello world");
	cout <<"a:"  << a << endl;
	cout << endl;

	//输出a占了多少个字节
	cout <<"size:" << a.size() << endl;
	cout <<"length:" << a.length() << endl;
	cout << endl;

	//输出系统给a一共开了多少空间
	cout <<"capacity:" << a.capacity() << endl;
	cout << endl;

	//将字符串的空间进行调整
	a.resize(5);
	cout << "resize之后:" << endl;
	cout << "a:" << a << endl;
	cout << "size:" << a.size() << endl;
	cout << "capacity:" << a.capacity() <<endl;
	cout << endl;

	//判断是否为空  1为空,0是不空
	cout << "empty:" << a.empty() << endl;
	cout << endl;

	//清除所有字符
	a.clear();
	cout <<"clear:" << a << endl;
	cout << endl;

	//判断是否为空  1为空,0是不空
	cout << "empty:" << a.empty() << endl;
	cout << endl;

	//为字符串预留空间
	cout <<"reserve前的capacity:" << a.capacity() << endl;
	a.reserve(100);
	cout <<"reserve后的capacity:" <<a.capacity() << endl;
	cout << endl;
}

注意:

            1 resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。

            2.resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

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

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

扩充:auto关键字 

   1.用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&

   2.当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

  3.auto不能作为函数的参数,可以做返回值,但是建议谨慎使用 auto不能直接用来声明数组

 auto会自动推导数据的类型,我们也可以看到auto与auto*没有区别。

 

#include<iostream>
using namespace std;
#include<string>
int main()
{
	string a("hello world");

	//访问方法:下标访问法
	cout << a[0] << endl;
	cout << a[6] << endl;
	a[0] = 'w';
	cout << a << endl;

	//1、下标遍历法
	cout << "下标遍历法:" << endl;
	for (int i = 0; i < a.size(); i++)
	{
		cout << a[i] << " ";
	}
	cout << endl;

	//2、迭代器法(正向)
	cout << "迭代器法(正向):" << endl;
	string::iterator it = a.begin();
    //auto it = a.begin();  与上面的效果一样
	for (; it != a.end(); it++)
	{
		cout << *it << " ";
	}
	cout << endl;

	//3、迭代器(反向)
	cout << "迭代器(反向):" << endl;
	string::reverse_iterator rit = a.rbegin();
    //auto it = a.rbegin();  与上面的效果一样
	while (rit != a.rend())
	{
		cout << *rit << " ";
		rit++;
	}
	cout << endl;

	//范围for法  底层还是迭代器的原理,速度与迭代器相似
	cout << "范围for法:" << endl;
	for (auto e : a)
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

 

4. string类对象的修改操作 

 

#include<iostream>
using namespace std;
#include<string>
int main()
{
	string a("hello world");
	cout << a << endl;
	cout << endl;

	//在末尾加入字符
	a.push_back('g');
	cout << "push_back后:" << a << endl;
	cout << endl;

	//在末端加入字符串
	a.append(" world");
	cout << "append后:" <<a << endl;
	cout << endl;

	//在末端随意添加
	a += "!!!!!";
	cout << "+=后:" <<a << endl;
	cout << endl;

	//返回C格式字符串
	const char* b= a.c_str();
	cout << "c_str:" <<b << endl;
	cout << endl;

	//从pos位置开始查找字符并返回其位置
	int npos1 = a.find('o');
	cout << "find:" <<npos1 << endl;
	cout << endl;

	//从pos位置开始从后往前查找字符并返回其位置
	int npos2 = a.rfind('o');
	cout << "rfind:" <<npos2 << endl;
	cout << endl;

	//从pos位置开始截取n个字符并返回
	string tmp1 = a.substr(npos1, npos2 - npos1);
	cout << "substr后tmp1:"<<tmp1 << endl;
	string tmp2 = a.substr(npos1);
	cout << "substr后tmp2:" << tmp2 << endl;
	cout << endl;

	//从指定的pos位置开始往后找
	int npos3 = a.find('o',npos1+1);
	cout << "从指定位置开始从前往后找:" << npos3 << endl;
	string tmp3 = a.substr(npos3);
	cout << "substr后tmp3:" << tmp3 << endl;
	return 0;
}

 5. string类非成员函数 

#include<iostream>
using namespace std;
#include<string>
int main()
{
	string a("hello ");
	string b("world");

	//涉及深层拷贝,不建议多用
	cout <<"operator+" << operator+(a, b) << endl;
	cout << "a+b:" << a + b << endl;
	cout << endl;

	//输入运算符重载
	string c;
	operator>>(cin, c);   //cin>>c;效果相似 录入空格之前的,并在遇到换行时,停止输入
	cout << "operator>>:" <<c << endl;
	cout << endl;

	//输出运算符重载
	cout << "operator<<:";
	operator<<(cout, a) << endl;   //cout<<a;效果相似
	cout << endl;

	//获取一行字符串
	cout << "getline:";  //即使是空格之后的也是可以录入的,遇到换行时停止输入
	string d;
	getline(cin, d);    //这个在这个程序中测不出来,需要单独测试
	cout << d << endl;
	cout << endl;

	return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

显示全文