【C++】string类(上)

简介: 【C++】string类(上)

1.为什么要学习string类

  • c语言的字符串是以’\0’结尾的一些字符的集合,比如存储你的家庭住址,修改成为新的住址,原来的住址短,现在的住址长,之前的字符串数组存不下,不能很好按需修改
  • c++提供一个类来管理字符串,这个类就叫string

2.标准库中的string类

1.string分类

  • string 是一个类模板,原型是一个 basic_string的类模板由typedef成为string
  • char(重点使用)

  • char:1个字节 ,即一个字符1个字节

  • 宽字符存在(使用相对偏少)

  • wchar_t :2个字节 ,即一个字符2个字节

  • C++11提供u16string和u32string(了解)

  • char16_t:2个字节 即一个字符2个字节
  • char32_t: 4个字节 即一个字符4个字节

上述多种string形式说明有管理不同字符数组的需求

ASCII是美国标准信息交换代码,用来在计算机里面存储和显示英文信息,通过26个字母、数字、标点符号,来建立关系形成映射表从而生成了编码表,调用对应的ASCII值来生成对应的符号,ASCII表只有128个字符,一个字节8个bit位就够了

为了支持显示除了英文以外的文字显示,就发明出了unicode (万国码),为每种语言的每个字符设定了统一并且唯一的二进制编码

  • 使用2个字节进行统一编码
  • 使用4个字节进行统一编码
  • UTF-16对应u16string ,UTF-32对应 u32string

2.string类对象的常见构造

  • 必须包含头文件< string >

1.string

  • string()——构造空的string类对象,即空字符串
  • string(const char*s) ——用常量字符串构造string字符串
#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s1;
    string s2("hello");
    //遍历数组并使每个字符+1
    for (size_t i = 0; i < s2.size();i++)
    {
        s2[i]++;
    }
    cout << s2 << endl;// 通过重载流提取(<<),string可以直接进行打印
    //ifmmp
    return 0;
}

string(const string&str,size_t pos,size_t len=npos);—— 拷贝str从pos开始的len个字符

如果len长度大于pos位置后的字符个数,则有多少取多少

若len没有给值,则会自动默认缺省值npos

  • size_t npos=-1,由于是无符号整形,实际上是-1的补码即整形最大值
#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s1("hello world");
    string s2(s1, 6, 5);//拷贝s1从第6个位置开始取5个字符
 string s3(s1, 6, 15);//由于pos为指向后取只有5个字符,小于15,有多少取多少
 string s4(s1, 6);//len缺省值为整形最大值,则一直从pos位置取到结尾
cout<<s2<<endl;
cout<<s3<<endl;
cout<<s4<<endl;
}

string(size_t n,char c); ——填string类对象前n个字符

int main()
{
    string s(10, '.');// 前10个字符为 .
    cout << s << endl;//..........
    return 0;
}

3. string类对象的容量操作

1.size

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s("hello world");
    cout << s.size() << endl;//11
    cout << s.length() << endl;//11
    return 0;
}
  • size和length两者功能相同,由于string发展历史造成的,最开始字符串的长度为length,后来为了和数据结构其他保持一致使用size更符合,所以推荐使用size

2.capacity

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s("hello world");
    cout << s.size() << endl;//11
    cout << s.capacity() << endl;//15
    return 0;
}

  • 有11个字符,但是空间大小为15(不包含/0)

3.reserve

#include<iostream>
#include<string>
using namespace std;
//扩容问题
int main()
{
    string s;
 //s.reserve(100);//提前开辟100个空间
    size_t sz = s.capacity();//sz代表原来的容量
    cout << "making a grow" << endl;
    for (int i = 0; i < 100; i++)
    {
        s.push_back('c');//不断在字符串后插入字符c
        if (sz != s.capacity())//扩容后,将sz值更新
        {
            sz = s.capacity();
            cout << "capacity changed:" << sz << endl;
        }
    }
}

  • 提前开辟空间,减少扩容,提高效率

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s("hello");
    s.reserve(100);
    cout << s.size() << endl;//5
    cout << s.capacity() << endl;//111
    return 0;
}
  • reserve只会改变capacity,不会改变size
  • size值没有改变依旧为5,capacity被提前开辟100个空间

4.resize

扩容+初始化

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s("hello");
    s.resize(100);
    cout << s.size() << endl;//100
    cout << s.capacity() << endl;//111
    return 0;
}
  • reserve既改变capacity,也会改变size
  • size值被改变为100,被修改的部分填的是缺省值’\0’,
    capacity值也被改变为111

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s("hello");
    s.resize(10,'x');//将size修改的值填成x
    return 0;
}
  • 可以手动添加字符填成自己想给的值

删除数据

#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s("hello");
    s.resize(2);//2<5,所以只保留前2个字符 
    cout << s << endl;//he
        cout << s.capacity() << endl;//15
    return 0;
}
  • 若resize值小于size值,可以删除数据,但不会改变容量

4. string类对象的修改操作

1.push_back

  • 在字符串后插入字符
#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s("hello");
    s.push_back(' ');
    s.push_back('!');
    cout << s << endl;//hello !
    return 0;
}

2.append

  • 在字符串后插入字符串
#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s("hello");
    s.append(" world!");
    cout << s << endl;//hello world!
    return 0;
}

3.operator+=

  • 字符串后插入字符/字符串/对象
#include<iostream>
#include<string>
using namespace std;
int main()
{
    string s("hello");
    s += ' ';//字符
    s+='!';
    s += "world";//字符串
    string s2("abc");
    s += s2;//对象
    cout << s << endl;//hello !worldabc
    return 0;
}

相比于push_back 插入字符和append插入字符串,operator+=方式更容易使用

相关文章
|
10天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
39 4
|
11天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
35 4
|
1月前
|
Java
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
本文深入探讨了Java中方法参数的传递机制,包括值传递和引用传递的区别,以及String类对象的不可变性。通过详细讲解和示例代码,帮助读者理解参数传递的内部原理,并掌握在实际编程中正确处理参数传递的方法。关键词:Java, 方法参数传递, 值传递, 引用传递, String不可变性。
56 1
【编程基础知识】(讲解+示例实战)方法参数的传递机制(值传递及地址传递)以及String类的对象的不可变性
|
1月前
|
安全 Java 测试技术
Java零基础-StringBuffer 类详解
【10月更文挑战第9天】Java零基础教学篇,手把手实践教学!
25 2
|
1月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
27 4
|
1月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
23 4
|
1月前
|
存储 安全 C++
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
21 1
|
1月前
|
数据可视化 Java
让星星月亮告诉你,通过反射创建类的实例对象,并通过Unsafe theUnsafe来修改实例对象的私有的String类型的成员属性的值
本文介绍了如何使用 Unsafe 类通过反射机制修改对象的私有属性值。主要包括: 1. 获取 Unsafe 的 theUnsafe 属性:通过反射获取 Unsafe类的私有静态属性theUnsafe,并放开其访问权限,以便后续操作 2. 利用反射创建 User 类的实例对象:通过反射创建User类的实例对象,并定义预期值 3. 利用反射获取实例对象的name属性并修改:通过反射获取 User类实例对象的私有属性name,使用 Unsafe`的compareAndSwapObject方法直接在内存地址上修改属性值 核心代码展示了详细的步骤和逻辑,确保了对私有属性的修改不受 JVM 访问权限的限制
52 4
|
1月前
|
存储 安全 Java
【一步一步了解Java系列】:认识String类
【一步一步了解Java系列】:认识String类
25 2
|
1月前
|
存储 编译器 C语言
【C++打怪之路Lv3】-- 类和对象(上)
【C++打怪之路Lv3】-- 类和对象(上)
17 0

热门文章

最新文章

下一篇
无影云桌面