0%

string类方法

从C字符串到C++的string类(in

从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这里使用了无参构造函数,建立空字符串s
  • string s(s1)是第一种的变体,s1是C字符串,而s是字符串对象

 

string类操作

追加

  • s1.append("1234") s1后追加1234
  • s2.append("1234",0,2) s2后追加12(从0个字符开始)
  • s3.append("1234",2) s3后追加12
  • s4.append(2,'1') s4后追加11(注意这里是单个字符,和下面的赋值一样)

赋值

  • s1.assign("1234") s1变成1234
  • s2.assign("1234",0,2) s2变成12(从0个字符开始)
  • s3.assign("1234",2) s3变成12
  • s4.assign(2,'1') s4变成11

处理

  • s1.at(1) 返回s1字符串下标1的单个字符char
  • s2.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) 返回1
  • s1.substr(1) 返回234

搜索

string s1("12341")

  • s1.find("23") 返回下标1
  • s1.find("23",3) 返回string::npos(从下标3开始找,没找着)
  • s1.find("1",3) 返回下标4

插入与替换

string s1("1234")

  • s1.insert(2,"66") s1变为123664
  • s1.insert(2,2,"66") s1变为12366664
  • s1.replace(1,2,"8") s1变为184

string对象在使用append、assign、erase、replace、insert之后,这些方法本身也会返回为结果字符串,例如以上s1.insert()=s1

迭代器

  • begin():指向容器第一个元素的位置(可读可写)
  • rbegin():指向容器最后一个元素的位置(可读可写)
  • cbegin():指向容器第一个元素的位置(只读)
  • crbegin():指向容器最后一个元素的位置(只读)
  • end():指向容器最后一个元素的下一个位置(可读可写)
  • rend():指向容器第一个元素前面的位置(可读可写)
  • cend():指向容器最后一个元素的下一个位置(只读)
  • crend():指向容器第一个元素前面的位置(只读)

迭代器失效:当容器扩容缩容时容易导致迭代器指向的对象错位,需要及时更新

数字、浮点数与字符串之间的变化

  • C字符串中的atoiatof 方法同样适用
  • 更方便的方法是使用<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