STL容器——string

        string是STL的字符串类型,通常用来表示字符串。而在使用string之前,字符串通常是用char*表示的。string与char*都可以用来表示字符串,那么二者有什么区别呢。

string和char*的比较
string是一个类, char*是一个指向字符的指针。
          string封装了char*,管理这个字符串,是一个char*型的容器
string不用考虑内存释放和越界
         string管理char*所分配的内存。每一次string的复制,取值都由string类负责维护,不用担心复制越界和取值越界等。
string提供了一系列的字符串操作函数(这个等下会详讲)

        

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

//1 string 的构造
void func1()
{
	//string();    //默认构造函数,构造一个空的字符串string s1
	string s1("123");

	string s2 = "adc";//带参数的构造函数string(const char *s);用字符串s初始化
	cout << s1 << ", " << s2 << endl;                  

	string s3 = s1;//拷贝构造函数:string(const string &str);构造一个与str一样的string

	string s4;
	s4 = s2;//赋值, string &operator=(const string &s); 把字符串s赋给当前的字符串
	cout << s3 << ", " << s4 << endl;   /*ps:
					string &assign(const char *s) 、
					string &assign(const string &s)  把字符串s赋给当前字符串
				        string &assign(int n,char c);    用n个字符c赋给当前字符串
					string &assign(const string &s,int start, int n); 把字符串s中从start开始的n个字符赋给当前字符串
					string &assign(const char *s, int n);  把字符串s的前n个字符赋给当前的字符串
					*/

	string s5(10, 'a');//用多个字符初始化(构造)string(int n,char c);//  用n个字符c初始化
	cout << s5 << endl;
}

//2、string 的遍历存取
void func2()
{
	string s1 = "hello world";

	//1、通过数组下标进行遍历
	for (unsigned int i = 0; i < s1.length(); i++)//int length() const;返回当前字符串的长度。长度不包括字符串结尾的'\0'。
		cout << s1[i];
	cout << endl;		// ps: bool empty() const;     //当前字符串是否为空

	//2、通过at()函数进行遍历
	for (unsigned int i = 0; i < s1.length(); i++)
		cout << s1.at(i);
	cout << endl;

	//3、string也有迭代器,通过迭代器遍历,拥有迭代器的容器都有两个函数
	                //----begin():返回指向当前容器的第一个元素的迭代器,
			//----end():返回指向当前容器最后一个元素的下一个元素的迭代器(类似字符串结尾\0的位置)
	string::iterator it = s1.begin();
	while (it != s1.end())
	{
		cout << *it;
		it++;
	}
	cout << endl;

	//4、operator[]和at()均返回当前字符串中第n个字符,但 []和at函数 有区别
	// [] 如果访问越界,[]在刚好越界时会返回(char)0,再继续越界时,编译器直接出错终止程序运行,不会抛出异常。
	// at 如果访问越界,会抛出一个异常
	try
	{
		for (unsigned int i = 0; i < s1.length()+1; i++)//让数组越界
			cout << s1.at(i);
		cout << endl;
	}
	catch(exception &e)
	{
		printf("抓到一个异常:%s\n", e.what());
	}
	
}

//3、string 和 char* 的转换
//const char *c_str() const;   //返回一个以'\0'结尾的字符串的首地址
void func3()
{
	string str = "123456";
	printf("str = %s\n", str.c_str());
}

//4、字符串的连接、拷贝、比较
void func4()
{
	string s1 = "hello ";
	string s2 = "world";
	s1 = s1 + s2;/*连接  string &operator+=(const string &s)、
			string &operator+=(const char *s);、
			string &append(const char *s)、
			string &append(const string &s);把字符串s连接到当前字符串结尾
		        string &append(int n, char c);   //在当前字符串结尾添加n个字符c
			string &append(const string &s,int pos, int n);//把字符串s中从pos开始的n个字符连接到当前字符串结尾
			string &append(const char *s,int n);  //把字符串s的前n个字符连接到当前字符串结尾
						*/
	cout << s1 << endl;

	s1 = "111" + s1 + "222";
	cout << s1 << endl;

	s1.append("asdaf");//把字符串s连接到当前字符串结尾
	cout << s1 << endl;

	/*拷贝: int copy(char *s, int n, int pos=0) const;  
	把当前串中以pos开始的n个字符拷贝到以s为起始位置的字符数组中,
	返回实际拷贝的数目。
	注意要保证s所指向的空间足够大以容纳当前字符串,不然会越界。*/
	char str[100] = {0};
	s1.copy(str, 6, 1);
	cout << str << endl;

	//比较     
	if (s1 == s2)
		cout << "s1 == s2" << endl;
	else
		cout << "s1 != s2" << endl;
	/*ps
	int compare(const string &s) const;  //与字符串s比较
	int compare(const char *s) const;   //与字符串s比较
	compare函数在>时返回 1,<时返回 -1,==时返回 0。
	比较区分大小写,比较时参考字典顺序,排越前面的越小。大写的A比小写的a小。
	*/
}

//5、查找和替换
void func5()
{
	string s1 = "111 hello 222 hello 333 hello 444 hello";
	/*
	查找:
	int find(const char *s, int pos=0) const;
	或
	int find(const string &s, int pos=0) const; 
	从pos下标位置开始查找字符串s在当前字符串中的位置
	如果存在则返回第一个子串的下标,不存在则返回-1

	int rfind(const char *s, int pos=npos) const;
	int rfind(const string &s, int pos=npos) const;
	//rfind是反向查找的意思,如果查找不到, 返回-1
	*/

	int index = s1.find("hello", 0);
	if (index == -1)
		cout << "不存在该字符串" << endl;
	else
		cout << "存在" << endl;

	/*替换:先删除,再插入
	string &replace(int pos, int n, const char *s);
	或
	string &replace(int pos, int n, const string &s);  
	//删除从pos开始的n个字符,然后在pos处插入串s

	void swap(string &s2);    //交换当前字符串与s2的值	
	*/
	s1.replace(4, 1, "adc");
	cout << s1 << endl;
	/*
	string s2 = "fizz";
	s1.swap(s2);
	cout << s1 << endl;
	*/

	//将s1 中的hello 替换成大写的 HELLO
	index = s1.find("hello", 0);
	while (index != -1)
	{
		s1.replace(index, 5, "HELLO");//在原先hello的位置删除5个字节长度(即hello),再插入HELLO
		index = s1.find("hello", index+5);//继续往后找下一个hello
	}
	cout << s1 << endl;
}

//6、删除和插入
void func6()
{
	string s1 = "111 hello 222 hello 333 hello 444 hello 555 hello"; 
	//1、通过迭代器
	//删除单个元素
	s1.erase(s1.begin());
	cout << s1 << endl;

	//删除多个元素:左闭右开 [s1.begin(), s1.begin()+3)
	s1.erase(s1.begin(), s1.begin()+3);
	cout << s1 << endl;

	//string &erase(int pos=0, int n=npos);
	//删除pos开始的n个字符,返回修改后的字符串
	string s2 = s1.erase(1, 2);
	cout << s1 << endl;
	cout << s2 << endl;
	//插入
	//第一个参数是插入位置的下标,第二个参数是要插入的元素
	s1.insert(0, "111");
	s1.insert(5, "adc");
	s1.insert(s1.length(),"AAA");
	cout << s1 << endl;
}

//7、可以用算法函数操作字符串
void func7()
{
	string s1 = "111 hello 222 hello 333 hello 444 hello 555 hello"; 

	//转换算法
	//要转换的起始位置,截止位置,存放转换结果的地址,转大写
	transform(s1.begin(), s1.end(), s1.begin(), toupper);//转成大写
	cout << s1 << endl;

	transform(s1.begin(), s1.end(), s1.begin(), tolower);//转成小写
	cout << s1 << endl;

	//逆序
	reverse(s1.begin(), s1.end());
	cout << s1 << endl;
}

//应用例题: 逆序长句,不逆序单词
void func8()
{
	string s = "You are from shanghai";
	reverse(s.begin(), s.end());//先整体逆序

	int begin = 0;
	int index = s.find(" ");//index为空格的下标位置,find不传第二个参数,默认是0(find第二个参数有默认值0)
	while (index != -1)//找到空格的情况下
	{
		reverse(s.begin()+begin, s.begin()+index);
		begin = index+1;//空格只占一个字节,从上个空格的后面开始继续找
		index = s.find(" ", index+1);
	}

	//最后一个单词不以空格结尾,最后一个单词在上面的循环中没有逆序
	reverse(s.begin()+begin, s.end());//逆序最后一个单词
	cout << s << endl;
}


int main()
{
	/*
	func1();
	func2();
	func3();
	func4();
	func5();
	func6();
	func7();
	*/
	func8();
	/*ps:返回由pos开始的n个字符组成的子字符串
	string substr(int pos=0, int n=npos) const;
	*/
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值