IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 初学STL——剖析string -> 正文阅读

[C++知识库]初学STL——剖析string

C语言中的字符串:C语言中,字符串是以’\0’结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
C++标准库中的string类:在使用string类时,必须包含#include头文件以及using namespace std;

1. string是表示字符串的字符串类
2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator> string;
4. 不能操作多字节或者变长字符的序列。

string类对象的常见构造:
在这里插入图片描述

void main()
{
	string s1; //定义空字符串
	cout << "s1= " << s1 << endl;

	//上下两个都是构造 (两者初始化都是可以的)
	string s2("HelloBit");
	cout << "s2= " << s2 << endl;
	string s3 = "HelloBitA";
	cout << "s3= " << s3 << endl;

	//string类对象中包含n个字符c
	string s4(5, 'a');
	cout << "s4= " << s4 << endl;

	//拷贝构造
	string s5(s4);
	cout << "s5= " << s5 << endl;
	string s6(s2, 5, 3);   //从某个位置开始  拷贝构造多少长度
	cout << "s6= " << s6 << endl;
	string s7("HelloBit", 5);
	cout << "s7= " << s7 << endl;  //从该字符串开始  拷贝多少长度

	const char* str = "abcdefg";
	string s8(str + 1, str + 4);
	cout << "s8= " << s8 << endl; //拷贝构造一个区间
}

string类对象容量操作
在这里插入图片描述

void main()
{
	//resize 会改变函数的本身(调整字符串长度)
	string s1;
	cout << "s1= " << s1 << endl;
	cout << "size=" << s1.size() << endl;
	cout << "capacity= " << s1.capacity() << endl;

	s1.resize(20, '@');  //当调整的容量大于初始化容量会自动扩
	cout << "s1= " << s1 << endl;
	cout << "size=" << s1.size() << endl;
	cout << "capacity= " << s1.capacity() << endl;

	s1.resize(30, 'a'); //不会覆盖 前20为@后10为a
	cout << "s1= " << s1 << endl;
	cout << "size=" << s1.size() << endl;
	cout << "capacity= " << s1.capacity() << endl;
}

void main()
{
    //调整容量空间
	//reserve 不改变字符串的本身
	string s1;
	cout << "s1= " << s1 << endl;
	cout << "size=" << s1.size() << endl;   
	cout << "capacity= " << s1.capacity() << endl; 

	s1.reserve(100); //预留100个字符串空间
	cout << "s1= " << s1 << endl;
	cout << "size=" << s1.size() << endl;
	cout << "capacity= " << s1.capacity() << endl; //这时候空间不一定就是100个

	//也可以从大往小调
	s1.reserve(10); //预留10个字符串空间
	cout << "s1= " << s1 << endl;
	cout << "size=" << s1.size() << endl;
	cout << "capacity= " << s1.capacity() << endl; //这时候空间不一定就是100个
}

void main()
{
	string s1("HelloBit");
	cout << "s1= " << s1 << endl;
	cout << "size=" << s1.size() << endl;  
	cout << "length= " << s1.length() << endl;  
	cout << "capacity= " << s1.capacity() << endl;  
	//当字符串容量小于需求的时候 编译器会自动扩容
	s1 += "abcdefghij";
	cout << "s1= " << s1 << endl;
	cout << "size=" << s1.size() << endl;
	cout << "length= " << s1.length() << endl;
	cout << "capacity= " << s1.capacity() << endl;
}

//string类对象的容量操作
void main()
{
	//操作过程中不关心\0的
	string s1("HelloBit");
	cout << "s1= " << s1 << endl;
	cout << "size=" << s1.size() << endl;  //求字符串的有效长度
	cout << "length= " << s1.length() << endl;  //一般情况下用length
	cout << "capacity= " << s1.capacity() << endl;  //求初始化存储空间(不同的编译器对初始化空间有不同的规定)
	s1.clear();
	cout << "s1= " << s1 << endl; //清空字符串

	string s2;
	cout << s2.empty() << endl;  //判断字符串是否为空
}

注意:利用reserve函数可以提高插入数据的效率,避免增容的开销。

void main()
{
    //利用reserve函数可以提高插入数据的效率,避免增容的开销
    string s;
    cout << "capacity= " << s.capacity() << endl;
    s.reserve(100);
    for (int i = 0;i <= 100;++i)
    {
        cout << "capacity= " << s.capacity() << endl;
        s.push_back(i + 1);
    }
}
1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
2. clear()只是将string中有效字符清空,不改变底层空间大小。
3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

string类对象的访问及遍历操作
在这里插入图片描述

//只要是字符串 可用迭代器
void main()
{
    //五个效果一样  都是访问字符串
    string s1("abcdxyz");
    string::iterator it = s1.begin();
    while (it != s1.end())
    {
        cout << *it;
        ++it;
    }
    cout << endl;
  
    cout << s1 << endl;

    for (const auto& e : s1)
        cout << e;
    cout << endl;

    for (int i = 0;i < s1.size(); ++i)
        cout << s1[i];
    cout << endl;

    string::reverse_iterator rit = s1.rbegin();
    while (rit != s1.rend())
    {
        cout << *rit;
        ++rit;
    }
    cout << endl;

string类对象的修改操作
在这里插入图片描述

//string类对象的修改操作
void main()
{
    //截取不影响原本的字符串
    string s = "abxyccb";
    cout << "s= " << s << endl;
    string s1 = s.substr(2,5);  //截取字符串的某一段
    string s1 = s.substr(2);  //从2开始一直到结尾
    cout << "s1= " << s1 << endl;
}

void main()
{
    //查找返回的不是地址  是下标
    string s = "abxcxyz";
    int index = s.find('x');
    cout << "index= " << index << endl;  //假如有两个x返回 第一个的下标
    int index = s.find('x', 3); //从3位置下标开始找
    int index = s.find("xyz");  //还可以查找字符串
    int index = s.find("xyz", 4, 3);  //从哪个位置查找多少个字符

    int index = s.rfind('x');  //反向查找

    if (index == string::npos)  //npos==null pos
        cout << "找不到" << endl;
    else
        cout << "index= " << index << endl;
}

void main()
{
    //返回c格式化字符串
    string s("abc");
    strlen(s.c_str());
}

void main()
{
    //operator+=操作
    string s("abc");
    string s1("qwe");
    //s += "xyz";
    s += s1;
    cout << "s= " << s << endl;
}

void main()
{
    //没有头插操作  会影响操作
    string s = ("abc");
    string s1 = ("qwer");
    cout << "s= " << s << endl;
    s.push_back('x'); //只能插字符

    s.append("xyz");  //追加操作可以追加字符串
    s.append("xyz", 2);  //追加两个字符
    s.append(s1, 0, 3); //追加一个字符串的一个范围
    s.append(3,'x');  //追加三个x

    cout << "s= " << s << endl;
}

注意

1. 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

string类非成员函数:多补充以下几个接口使用

//查找第一个
void main()
{
    string s1 = "abcxyzab";
    int index = s1.find_first_of('b'); 会查找这个字符串第一次出现的位置
    int index = s1.find_first_of("yxz");   //会查找这个字符串第一次出现的位置
    int index = s1.find_first_not_of("yxza"); //查找不在这个字符串里的第一个位置
    int index = s1.find_last_of("yxza");  //查最后一次出现的位置
    cout << index << endl;
}

//交换
void main()
{
    string s1 = "abc";
    string s2 = "xyz";
    s1.swap(s2);
    cout << s1  << endl;
    cout << s2  << endl;
}

//插入 删除
void main()
{
    string s1 = "aac";
    s1.insert(0, "xyz");  //在0位置插xyz
    //s1.erase(s1.begin(), s1.end());
    s1.erase(2, 5);  //删除2-5
    cout << s1 << endl;
}

//比较
void main()
{
    string s1 = "aac";
    string s2 = "aac";
    if (s1.compare(s2) == 0)
        cout << "s1==s2" << endl;
}

//at
void main()
{
    string s1 = "abc";
    for (int i = 0;i < s1.size();++i)
        cout << s1[i];
    cout << endl;

    for (int i = 0;i < s1.size();++i)
        cout << s1.at(i); //检查是否越界
    cout << endl;
}

//赋值
void main()
{
    string s1 = "abc";
    string s2 = "xyzsadasdassd";
    //s1.assign("xyz");  //赋值操作会改变对象本身
    //string& rs = s1.assign("xyz");  //用引用来接受
    s1.assign(s2);  //赋值字符串也是可以的
    cout << "s1" << endl;
}


//string类的非成员函数
void main()
{
    //比较字符串大小
    string s1 = "abc";
    string s2 = "xyz";

    if (s1 > s2)
        cout << "s1>s2" << endl;
    else
        cout << "s2<s1" << endl;
}

void main()
{
   //getline 获取一行字符串
    string s;
    getline(cin, s);  //输入字符串的方法
    cout << s << endl;
}

void main()
{
    //operator+
    string s1 = "abc";
    string s2 = "xyz";
    string s = s1 + s2;
    cout << s << endl;
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-08 13:38:17  更:2021-12-08 13:38:29 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:32:15-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码