聚焦 string:C++ 文本处理的核心利器--《Hello C++ Wrold!》(10)--(C/C++)

文章目录

前言

在 C++ 编程中,string 类是处理文本数据的核心工具,凭借动态扩容机制与丰富接口,成为日常开发中高频使用的基础组件。从力扣算法题里数字字符串的逐位相加,到实际项目中文本的解析与格式化,string 类的灵活应用直接影响代码效率与可读性。无论是reserveresize的扩容策略差异,还是find系列接口的精准检索技巧,亦或是字符串与数字的双向类型转换,掌握这些实用知识能让你在文本处理场景中事半功倍。

本章节将围绕 string 类的核心接口展开详解,结合经典例题与性能优化实践,带你系统掌握从基础操作到高级应用的全流程技巧。无论你是初涉 C++ 的新手,还是希望提升字符串处理能力的开发者,这里都将成为你高效驾驭 string 类的起点,为深入 STL 编程与复杂文本场景开发奠定基础。

初步认识STL

STL的底层实现必须要会(面试时会考)

阅读STL源代码的话,最好选择SGI版本的

STL有六个组成部分:仿函数,算法,迭代器,空间配置器,容器,配接器

容器的本身是类

虽然有了这些,但是C语言里面的知识也不能忘,因为面试时会被问到

容器不一定都有反向迭代器

string

使用string类时,必须包含#include头文件(这里的头文件是string)及using namespace std(或者eg:std::string这样搞)

但是string不属于STL,但是和STL很接近
注意点:

1.如果直接打印一个 char 类型的 \0,cout 会将其视为不可见字符(无输出),但不会终止打印。
和vector的区别:1.string自带\0 2.string有很多专属的接口,比如:+

常见接口

不常见的要用时到时候查就行 这下面介绍的都是成员函数

以下说的最后一个地方不是指\0

string类对象的常见构造

c++ 复制代码
string()  -- 构造空的string类对象,也就是空字符串
string(const char*s) -- 用C语言风格的字符串(""的那种)构造string类对象
比如: string s1("hello");
string(size_t n,char c) -- 构造出的string类对象中包含n个字符c
string(const string&s) -- 也就是调用拷贝构造函数

引申注意:不加其他操作的话,字符串的类型是const char*或者char[]

复制代码
                                             单个字符的类型是char

注意:string不能隐式类型转换成字符串,字符串可以隐式类型转换成string

string类对象的容量操作

size--返回字符串有效字符长度 --像这种不可能是负数的东西,库里面一般搞成size_t类型的

c++ 复制代码
注意点:长度为1时,s1.size()/2-1就会那啥
string不看\0,以size为终止算长度

length--返回字符串有效字符长度(和size没有区别)

c++ 复制代码
s1.size();   s1.length();
要注意的是,他们都不会算上'\0',但是string里面是有'\0'的
s1[s1.size()]下面正好存的是\0
要注意的是:s1.size()和sizeof(s1)区分
sizeof(s1)那个是内存对齐那个算对象一共占用的空间

capacity--返回空间总大小(没有算上\0

c++ 复制代码
用法:s1.capacity();

empty--检测字符串释放为空串,是空返回true,否则返回false

c++ 复制代码
用法: if(s1.empty())

clear--清空有效字符,但是不会释放空间(size变为0,capacity不会变)

c++ 复制代码
s1.clear();

reserve--为字符串预留空间(避免编译器频繁扩容浪费时间)

resize--将有效字符的个数改成n个,多出的空间用字符c填充(无c就用的0)

c++ 复制代码
用法:void reserve (size_t n = 0);
void resize (size_t n);或者void resize (size_t n, char c);
注意:reserve和reverse要区分
reserve和resize还有区别就是:resize一定会改变size()的结果,reserve不会

引申:具体扩容多少要看编译器(但是很少能原地扩容),不是reserve和resize里面写多少就多少的
缩容的话本质上是时间换空间(系统是不支持分段缩容的),一般编译器不会去缩容;
目前指知道clear之后再用reserve或resize可以缩容(capacity就会变了)

string类对象的访问及遍历操作

operator[pos] -- 返回pos位置的字符(第一个位置是[0])

begin--获取第一个字符的迭代器 end--获取最后一个字符的下一个位置的迭代器

rbegin--获取最后一个字符的迭代器 rend-获取第一个字符的上一个位置的迭代器(这里的迭代器其实是反向迭代器)

c++ 复制代码
rbegin和rend的迭代器的方向是反着的,比如:it是迭代器,it++就向前走了一个位置
引申:迭代器的类型很长,一般都是用的auto解决(迭代器是一种类型,类似指针;也可以*)
迭代器的类型有很多种:比如: const_iterator  iterator
不是const的话,可以通过迭代器修改字符

范围for

string类对象的修改操作

push_back--在字符串末尾插入字符c

append--在字符串末尾插入一个字符串

operator+=--在字符串末尾追加一个字符串(一般用的这个)

c_str--返回C风格的字符串(有时要用c语言函数,而那些函数识别不了string类型)

c++ 复制代码
用法: s1.c_str();

find--从字符串pos位置(含这里)开始往后找字符串,返回字符串第一个字符在字符串中的位置(返回的是第一次匹配时的)

rfind--从字符串pos位置(含这里)开始往前找字符串,返回字符串第一个字符在字符串中的位置(返回的是最后一次匹配时的)

c++ 复制代码
这俩个如果一直没能匹配到的话会返回npos(也就是size_t类型的-1)
注意:迭代器和npos前面要加上域名
比如:string::iterator和string::npos才行

find_first_of--在字符串中从左到右搜索,返回第一个出现在指定字符集合中的字符的位置

find_last_of--从右到左搜索,返回第一个出现在指定字符集合中的字符的位置

c++ 复制代码
找不到的话都是返回npos

substr--在str中从pos位置开始,截取n个字符,然后将其返回

c++ 复制代码
string substr (size_t pos = 0, size_t len = npos) const;
用法: string str3 = str1.substr (pos);

要注意的是:虽然string里面可以存中文,但是中文++的结果可能跟自己想的不一样,而且两个中文不一定只占string[]里面的0和1两个位置,可能会占更多位置

string类非成员函数

operator+ --尽量少用,因为传值返回,导致深拷贝效率低

operator>> --输入运算符重载

operator<< --输出运算符重载

getline --获取一行字符串(解决cin遇到空格不行的场景,getline默认是遇到换行符停止)

relational operators --大小比较(也是用字典序去比较的)

包含在string头文件下的好用函数

stoi-把数字字符串转换成int类型的

stod-把数字字符串转换成double类型的

to_string-把整数和浮点数转换成字符串

作业部分

c++ 复制代码
力扣 字符串相加
主要问题:就是把数字和字符串混一起搞了(没去分辨哪个是数字,哪个是字符导致的问题)
数字转字符要eg:to_string
字符转数字要eg:a-'0'
混一起搞就会出现输出是eg:\u这些

力扣 字符串相加

c++ 复制代码
代码展示:
class Solution {
public:
    string addStrings(string num1, string num2) {
        string num3;
        //让num1是最大的那个
        if(num1.size()<num2.size()||(num1.size()==num2.size()&&num2>num1))
        swap(num1,num2);
        int ret = 0;
        int partsum = 0;
        int gap = num1.size()-num2.size();
        for(int i = num2.size()-1;i>=0;i--)
        {
          partsum = num2[i]+num1[i+gap]+ret-'0'-'0';
          ret = partsum/10;
          partsum%=10;
          num3+=to_string(partsum);//最后要反转一下

        }
        //num1还有gap个数没搞
        for(int i = gap-1;i>=0;i--)
        {
            partsum = num1[i]+ret-'0';
            ret = partsum/10;
          partsum%=10;
          num3+=to_string(partsum);//最后要反转一下

        }
        if(ret==1)   num3+=to_string(ret);
        reverse(num3.begin(),num3.end());
        return num3;
    }
};
c++ 复制代码
HJ1 字符串最后一个单词的长度
注意点:像这种有空格的要读取时,不能用cin,要eg:getline(cin,s1);

      还有eg:for(int i = 0;i<n;i++);
           for(int i = 0;i<n;i++){}
//前两个是一个意思
           for(int i = 0;i<n;i++)
//这个是后面紧跟for或者while的话形成嵌套循环
还有,注意是2*k不是2k!

HJ1 字符串最后一个单词的长度

c++ 复制代码
代码展示:
#include <iostream>
#include<string>
using namespace std;
int main()
{
    string s1;
    getline(cin,s1);
    int count = 0;
    auto i = s1.end()-1;
     for(;*i==' ';i--);

    for(;*i!=' ';i--)
    {
        count++;
        if(i == s1.begin())   break;
    }
    cout<<count<<endl;
    return 0;
}
相关推荐
java金融1 分钟前
FactoryBean 和BeanFactory的傻傻的总是分不清?
java·后端
独立开阀者_FwtCoder18 分钟前
Nginx 通过匹配 Cookie 将请求定向到特定服务器
java·vue.js·后端
名曰大神21 分钟前
AEM6.5集成Redis详细步骤(附代码)
java·redis·demo·aem
带刺的坐椅29 分钟前
Solon AI 五步构建 RAG 服务:2025 最新 AI + 向量数据库实战
java·redis·ai·solon·rag
用户686916134901 小时前
哈希表实现指南:从原理到C++实践
数据结构·c++
ZackSock1 小时前
从零实现 RAG
算法
Jolyne_1 小时前
前端常用的树处理方法总结
前端·算法·面试
东阳马生架构1 小时前
商品中心—7.自研缓存框架的技术文档
java
大老板a2 小时前
c++五分钟搞定异步处理
c++
uhakadotcom3 小时前
完了,AI中台比数据中台更短命
面试·架构·github