【C++】string字符串 / string类

C++的标准库中,提供了一种用来表示字符串的数据类型string,这种类型能够表示长度可变的字符序列,不用担心赋值越界和取值越界等。

string 是C++风格的字符串,而 string 本质上是一个类,类内部封装了 char* ,管理这个字符串。

string类型也定义在命名空间std中,使用它必须包含string头文件。

#include<string>
using namespace std;

初始化和赋值字符串

我们已经接触过C++中几种不同的初始化方式,string也是一个标准库类型,它的初始化与vector非常相似。

	// 默认初始化,空字符串
	string s1;
	const char* str1 = "hello world"; // c_string风格,类比于string
	
	// 用另一个字符串变量,做拷贝初始化
	string s2 = str1; // 注意只是将s1中的字符串拷贝给s2,以后操作s1,对s2无影响
	string s2(str1); // 也可以调用拷贝构造函数

	string str2;
	str2 = 'a';
    // string str2 = 'a' 这样是不对的!

	// 用一个字符串字面值,做拷贝初始化
	string s3 = "Hello World!";
	// 用一个字符串字面值,做直接初始化
	string s4("hello world");
	// 定义字符和重复的次数,做直接初始化,得到 hhhhhhhh
	string s5(8, 'h');

	// 通过str.assign()赋值
	string str4;
	str4.assign("hello c++"); // 直接赋值

	string str5;
	str5.assign("hello c++",3); // str5 = “hel”

	string str6;
	str6.assign(str5); // str6 = "hel"

	string str7;
	str7.assign(5, 'x'); // str7 = "xxxxx"

操作字符串

	string str = "hello world";
	// 获取第3个字符
	cout << "str[2] = " << str[2] << endl;
	// 将第1个字符改为'H'
	str[0] = 'H';
	// str[i] 和 str.at(i) 同理
	// 将最后一个字符改为'D'
	str[str.size() - 1] = 'D';
	cout << "str = " << str << endl;

	// 使用string方法
	
	// 查找
	string str1 = "abcdefgde";
	int pos = str1.find("de");
	int pos1 = str1.rfind("de");
	// pos = 3;  pos1 = 7;
	
	// 替换
	str1.replace(1, 3, "1111");
	// str1 = "a1111efgde";

	// 插入
	str.insert(1, "111");
	// str = "H111ello worlD"
	
	// 删除
	str.erase(1, 3);  //从1号位置开始3个字符
	// str = "Hello worlD"

	// 获取子串
	string subStr = str.substr(1, 3);
	// subStr = "ell"

总结:

  • find查找是从左往后,rfind从右往左
  • 找到字符串后返回查找的第一个字符位置,找不到返回-1

注意:不能越界访问;如果直接越界访问并赋值,有可能导致非常严重的后果,出现安全问题

对于拷贝可能出现的问题:

例如:遍历所有字符,将小写字母换成大写:

	// 遍历字符串中字符,将小写字母变成大写
	for (int i = 0; i < str.size(); i++)
	{
		str[i] = toupper(str[i]);// string的一个函数toupper,可以把传入的字符转换成大写并返回
	}
	//以下是错误代码:
	for (int i = 0; i < s.length(); i++)
  	{
    	s1[i] = toupper(s[i]);
  	}

错误代码无法将s中的字符全部转换为大写字母并赋值给s1字符串的原因是,s1字符串在循环中访问索引i的时候是无效的,s1[i]访问索引i的操作将导致未定义行为,因为s1的大小为0,没有有效的索引。

在C++中,std::string是一个可变长度的字符序列,可以通过push_back()+=运算符来添加字符。

字符串相加(拼接)

string本身的长度是不定的,可以通过“相加”的方式扩展一个字符串。

	// 字符串相加(拼接)
	string str1 = "hello", str2("world");
	string str3 = str1 + str2;                  // str3 = "helloworld"
	string str4 = str1 + ", " + str2 + "!";    // str4 = "hello, world!"
	//string str5 = "hello, " + "world!";        // 错误,不能将两个字符串字面值相加

	string str6 = "I";
	str6.append(" love ");
	str6.append("game abcde", 4); // str6 = "I love game"
	//str6.append(str);  可以追加字面量或者字符串变量
	str6.append(str2, 4, 3); // 从下标4位置开始 ,截取3个字符,拼接到字符串末尾

比较字符串

string类还提供几种用来做字符串比较的运算符,“==”和“!=”用来判断两个字符串是否完全一样;而“<”“>”“<=”“>=”则用来比较两个字符串的大小。这些都是关系型运算符的重载。

	str1 = "hello";
	str2 = "hello world!";
	str3 = "hehehe";

	str1 == str2;    // false
	str1 < str2;     // true
	str1 >= str3;     // true
	// int ret = str1.compare(str2) 同理可以用string方法比较

字符串比较的规则为:

  • 如果两个字符串长度相同,每个位置包含的字符也都相同,那么两者“相等”;否则“不相等”;
  • 如果两个字符串长度不同,而较短的字符串每个字符都跟较长字符串对应位置字符相同,那么较短字符串“小于”较长字符串;
  • 如果两个字符串在某一位置上开始不同,那么就比较这两个字符的ASCII码,比较结果就代表两个字符串的大小关系
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秀秀_heo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值