从C字符串到C++的string类
C字符串以空终结符(‘\0’)结尾,使用时底层逻辑是暴露的,一般用于代码人员了解字符储存机制而使用。而string类则隐藏了字符串的底层储存,代码人员不需要去了解细节。
string类很好的体现了类的性质,在使用string类时,能更好的理解类、面向对象思想的应用
例如:
string s = "welcome to C++"
这句形似C字符串的字符创建方式其实略微浪费了计算机系统资源,因为他是先是利用"welcome to C++"建立字符串对象,然后再将这个对象拷贝给s,其实是两个步骤
后面给gpt检查的时候说这个思想不一定正确,因为编译器的返回值优化策略会避免这个问题,不过也不用在乎这个了
一下方式是更符合类的行为逻辑的:
string s("Welcome to C++")
括号显然是利用类的构造函数string s
这里使用了无参构造函数,建立空字符串sstring s(s1)
是第一种的变体,s1是C字符串,而s是字符串对象
string类操作
追加:
s1.append("1234")
s1后追加1234s2.append("1234",0,2)
s2后追加12(从0个字符开始)s3.append("1234",2)
s3后追加12s4.append(2,'1')
s4后追加11(注意这里是单个字符,和下面的赋值一样)
赋值:
s1.assign("1234")
s1变成1234s2.assign("1234",0,2)
s2变成12(从0个字符开始)s3.assign("1234",2)
s3变成12s4.assign(2,'1')
s4变成11
处理:
s1.at(1)
返回s1字符串下标1的单个字符chars2.erase(1,2)
删除s2从下标1开始的两个字符s3.clear()
s3被清空s4.empty()
以bool格式返回,检查s4是否为空s5.c_str()
s5以C字符串char[]的形式返回
查看:
s1.size()
和s1.length()
都是返回s1长度int值s2.capacity()
返回分配的存储空间大小
系统为string分配的存储空间字节大小大于本身大小,初始会设置一个阈值,若建立的字符串表面量大小小于这个阈值,则会在栈中直接分配这个阈值大小的存储空间,叫做小型字符串优化;若大于这个阈值,string对象内部会隐式new操作在堆中根据字符串大小分配内存。
这个阈值和编译器相关,常用的Visual C++是15
当使用push_back操作扩容时,若超出初始分配的大小,则会对堆内存进行扩容
比较:
s1.compare(s2)
s1与s2进行ASCII码比较,返回正数、0、负数
获取子串:
string s1("1234")
s1.substr(0,1)
返回1s1.substr(1)
返回234
搜索:
string s1("12341")
s1.find("23")
返回下标1s1.find("23",3)
返回string::npos(从下标3开始找,没找着)s1.find("1",3)
返回下标4
插入与替换:
string s1("1234")
s1.insert(2,"66")
s1变为123664s1.insert(2,2,"66")
s1变为12366664s1.replace(1,2,"8")
s1变为184
string对象在使用append、assign、erase、replace、insert之后,这些方法本身也会返回为结果字符串,例如以上s1.insert()=s1
迭代器:
begin()
:指向容器第一个元素的位置(可读可写)rbegin()
:指向容器最后一个元素的位置(可读可写)cbegin()
:指向容器第一个元素的位置(只读)crbegin()
:指向容器最后一个元素的位置(只读)end()
:指向容器最后一个元素的下一个位置(可读可写)rend()
:指向容器第一个元素前面的位置(可读可写)cend()
:指向容器最后一个元素的下一个位置(只读)crend()
:指向容器第一个元素前面的位置(只读)
迭代器失效:当容器扩容缩容时容易导致迭代器指向的对象错位,需要及时更新
数字、浮点数与字符串之间的变化
- C字符串中的
atoi
与atof
方法同样适用 - 更方便的方法是使用
<sstream>
头文件中的stringstream类
示例:
stringstream ss;
ss<<1.255;
string s == ss.str();
上面是官方书给的示例代码,不过我更喜欢这样用:
stringstream ss;
string s;
ss<<1.255;
ss>>s;
<sstream>
类会利用C++的类型系统和运算符重载来处理不同类型的数据,更加安全
stringstream类特有的输入输出流特点还方便了字符串抽取单词,因为这个方法会自动分割空格,将单词一个个存入输入流中
string text("abcd abc ab");
stringstream ss(text);
string word;
while(!ss.eof()){
ss >> word;
cout << word << endl;
}
输出:
abcd
abc
ab