C++ string的介绍

本文详细介绍了C++标准库中的string类,包括定义、初始化、读取、拼接、增删改查等基本操作,以及如何进行字符串查找、替换和转换。

一. 简介

        在 C 语言中如果想要定义一个字符串一般是通过定义 char * 或者 char 类型数组来实现,这种 char * 或者 char 数组很容易造成非法内存访问的问题,在 C++ 标准库中有一种可变长字符串类型 string,它可以帮助我们更加方便地定义以及使用字符串。使用前需要包含头文件 <string>,注意不是 <string.h> 后者是 C 语言中字符串处理函数,如 strlen,strcat 使用时才需要包含的头文件。

        string 是一个标准库里的类,它封装了 char * 管理这个字符串,使用 string 不需要担心内存越界问题,string 还提供了许多字符串的高级操作,比如插入,删除,查找等。

 

二. 定义和初始化string对象

string s1;                              // 空字符串

string s2 = "I Love C++";     // 把 "I Love C++" 这个字符串拷贝到了 string 管理的字符串内容的空间中,不包含末尾的 '\0'

string s3("I Love C++");       // 含义上跟上面类似

string s4(s2);                       // 通过 s2 拷贝构造

string s5(5,'a');                    // s5 的字符串内容为 "aaaaa" 

 

三. string对象的常用操作

1. string对象的读取

(1)使用 cin 读取 string 对象

cin >> s1;                            // 可以通过 cin 输入值给 string 对象,使用 cin 输入时,前面的空白字符会被忽略,直到再遇见

                                           // 空白字符就停止输入,如果输入 "    Hello,world Hello",那么 s1 的内容为 "Hello,world"

 

(2) 使用 getline 函数读取一整行数据给 string 对象

有时我们希望能够保留输入前的空格,比如能将 "    Hello,world Hello" 所有字符都读入 string 字符串中,此时用 cin 就不行了,应该使用 getline。getline 会读取一整行数据,直到遇到 \n 再停止,最后 string 中并不存放 \n

string s1;

getline(cin,s1);                   // 输入 "    Hello,world Hello",可以将所有的字符都读取到 s1 中

 

2. 访问字符串的第pos个下标的元素

        假设现在有一个 string str = "I Love C++";使用 str[0] 代表访问字符串 "I Love C++" 中的下标为 0 的元素,即为 'I',也可以使用 str.at(0) 去访问下标为 0 的元素,区别在于:前者如果下标越界了不会抛出异常,而后者如果下标越界了会抛出异常,所以可以使用 try-catch 去接收并处理。

 

3. 字符串的拼接

(1)使用string类内部重载的 + 运算符实现拼接

string s1 = "I Love";

string s2 = "C++";

string s3 = s1 + s2;

        字符串拼接可以使用 + 运算符。可以使用一个 string 与一个 char * 字符串拼接起来,支持链式但是注意两个 char * 字符串不能挨在一起,比如 string str = "hello" + str1 + "world" 是合法的,但是 string str = "hello" + "world" + str1 是不合法的(str1 是一个已经定义的对象)。

 

(2)使用string的append成员函数

string s1 = "I Love";

s1.append("C++");

        可以使用 append 成员函数,它总是把新字符追加到 string 的末尾,该成员函数的参数也可以是一个 string 对象,同时还可以指定要追加的长度等。

 

4. 字符串的增(insert)

string s1 = "Love C++";

str1.insert(0,"I ");    // 表示在下标为 0 的地方插入 "I ",插入后结果为 "I Love C++"

 

5. 字符串的删(erase)

string s1 = "I Love C++ and Java";

s1.erase(10,9);      // 表示从下标为 10 的地方开始删除(包括该字符),删除 9 个元素,所以删除后结果为 "I Love C++"

 

6. 字符串的改(replace)

string s1 = "I Love Java";

s1.replace(7,4,"C++");     

// 第一个参数表示从下标为几的位置开始替换,第二个参数表示要被替换的元素个数有多少,包括第一个参数下标的那个元素

// 第三个参数表示替换为什么,所以上述替换完结果为 "I Love C++"

 

7. 字符串的查找

(1)简单搜索查找  

        string 中的查找指定字符串可以使用 find 或者 rfind,前者是从下标为 0 的地方开始往后查找,后者是从最后一个元素的地方开始往前查找。使用 find 或者 rfind 查找想要的字符子串时,当查找到时函数返回该字符子串首元素的下标位置,当查找不到想要的字符子串,函数返回 string::npos,注意查找的子串是大小写敏感的

string s1 = "Hello,C++;Hello,Java;Hello,Python;";

int pos = s1.find("Hello");

if(pos != string::npos)

{

       cout << "查找到了,第一次出现的位置是:" << pos << endl;

}

 

(2)查找与给定字符串中任何一个字符匹配或者不匹配的位置

        假设现在有一个 string 对象  s = "hello2c++unity3d",想要查找字符串中第一个数字出现的位置,我们可以使用 find_first_of 函数,用法:s.find_first_of(args),即在 s 中查找 args 中任何一个字符第一次出现的位置。因此我们可以定义一个 string fmt("123456789"),然后 auto pos = s.find_first_of(fmt) 就可以查找到 s 中第一个数字出现的位置,如果想要查找最后一个数字出现的位置,调用 s.find_last_of(args) 即可。如果想要查找第一个不在 fmt 指定的字符列表中出现的字符,使用 s.find_first_not_of(fmt) 即可。

 

8. 使用c_str()可以返回char *,指向string中包含的字符串内容

一般是用在一些需要兼容旧库接口的地方。

string s1("l Love C++");

const char *ps1 = s1.c_str();

实现一个小demo:把字符串中所有的 "Hello" 都替换为 "hello"。

string s2("Hello,C++;Hello,Java;Hello,Python;");

while(s2.find("Hello") != string::npos)

{

        s2.replace(pos,strlen("Hello"),"hello");

        pos += strlen("hello");

}

cout << "替换后的内容为:" << s2 << endl;

 

9. 返回字符串中的子串(substr)

        使用 string 类提供的 substr 成员函数,用法:s.substr(pos, n) ,s 是一个 string 对象,pos 指定起始的位置,n 表示要拷贝几个字符。

string s1("Hello,world");

string s2 = s1.substr(0,5);        // s2 = hello

 

10. string 对象与数值转换

int i = 42;

string s = to_string(i);        // 将整数 i 转为字符表示形式

double d = stod(s);            // 将字符串 s 转为浮点类型

还有 stoi,stol,stoul,stoll,stoull,stof,stod,stold 等转换函数,分别是将 string 转换为 int, long, unsigned long ,long long, float, double, long double。如果调用这些函数不能将 string 转换为一个数字,则抛出 invalid_argument 异常,如果转换后的数字无法用任何类型来表示,则抛出 out_of_range 异常。 

 

四. sizeof(string)的大小问题

        string 是一个标准库里的类,它封装了 char * 用来管理字符串,那么使用 sizeof 计算 string 的大小应该是多少呢?string 的实现在各个版本的库中可能有所不同,但是在同一库中,无论你的 string 里放多长的字符串,它的 sizeof() 都是固定的,与存放字符串的长度无关。 

        在我的 VS2017 测试中发现,sizeof(string) == 28,当 string 存放的字符串内容比较短时,字符串的内容存放在这个 string 对象所占的地址空间内部,当 string 中字符串太长,字符串的内容就不存放在 string 这个对象的空间内了,而是在 string 空间外申请一块内存存放,string 中有一个指针去指向这个地址。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

椛茶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值