详细介绍:C++ 中string的用法

1.6.1 string类概述

string C++ 标准库(STL)提供的字符串处理类,封装了字符串的存储、修改、查找等功

能,相⽐传统的char[]C ⻛格字符串),具有⾃动内存管理、丰富的成员函数、类型安全等优

⽇常开发中处理字符串的⾸选⼯具。就是势,

今天围绕string核⼼⽤法展开,结合代码⽰例解析关键功能,覆盖初始化、转换、输⼊输出、容量控制、修改、查找、⽐较等场景。

1.6.2 string的初始化与赋值

string给予多种初始化⽅式,赋值运行也⽀持不同类型的右值,灵活性⾼。

1.6.2.1初始化⽅式(4 种核⼼场景)

void func(int a, int b = 20){...}

void func(int a){...}

void main()

{

// func(10); //错误:编译器无法确定调用哪个(产生歧义)

}

字⾯量初始化

string

str1("hello");

C ⻛格字符串(const char*)初始化

拷⻉初始化(构 造)

string str2(str1);⽤另⼀个string对象拷⻉创建(调⽤拷⻉构造函数)赋值初始化

string str3 = str1;等价于拷⻉初始化,语法糖形式直接赋值字⾯量

string str4 = "world"; C ⻛格字符串直接赋值初始化

1.6.2.2赋值操作

初始化后可利用= 重新赋值,⽀持两种赋值源:

注意:赋值会覆盖原字符串内容,且string会⾃动管理内存(⽆需⼿动释放旧内容)

1.6.3 stringchar*的转换

C++中部分场景需要char* 类型(如 printfC语⾔接⼝),string提供 c_str()实现转换。

// string初始化

string str;

string str2= "world"; // world

// 用另一个string对象赋值

str = str2; // world

// c风格字符串复制

str = "123123";

1.6.3.1核⼼⽅法:c_str()

机制:返回⼀个指向string内部字符数组的const char*指针,该数组以\0 结尾(兼容C⻛格字符串)

代码⽰例:

关键注意事项:

1. 返回值是 const char*,禁⽌强制转换为char* 后修改内容,否则会触发[未定义⾏ 为](如内存错误)。

❌ 错误⽰例:

(破坏string内部结构)。

2. 指针有效期:仅在string对象未被修改(如append/ erase )且未被销毁时有效。若string被修改,指针可能失效(内存重新分配)。

1.6.4 string的输⼊与输出

string⽀持C++标准IO流( cin/cout),但需要注意输⼊的分隔符特性。

#include <iostream>

#include <cstdio>

stringstr3("yueqian");

const char* ptr = str3.c_str();

printf("%s\n",ptr);

char* ptr = (char*)str.c_str(); ptr[0] = 'a';

1.6.4.1输出:cout << string

直接通过 cout 输出,⽆需处理\0 ,简洁直观:

1.6.4.2输⼊:cin >> stringgetline

cin >> string:默认分隔符输⼊

规则:以(空格、制表符、换⾏符)为分隔符,仅读取第⼀个分隔符前的内容。

⽰例:

getline(cin,string):整⾏输⼊

场景:需要读取包含空格的整⾏字符串

⽰例:

注意:若 getline前使⽤过 cin >>cin 会将换⾏符留在输⼊缓冲区,导致getline读取空串,需⽤cin.ignore()清除缓冲区。

stringstr("hello string");

cout <<str <<endl; // 输出:hello string

string str;

cin >>str; // 若输入:“hello world”, str仅存储 hello

cout <<str <<endl; // 输出:hello

string str;

cin.ignore(); // 若之前用了cin >>需清除缓冲区残留的换行符。类似于c语言中的

while(getchar() != '\n')

getline(cin, str); // 若输入:“hello world”, str存储 hello world

返回值

size()返回字符串实用字符个数(不 含'\0'str.size()

length ()size()完全等价(历史兼 容接⼝)

str.length()

capacity()返回当前内存可容纳的最⼤字 符数(不扩容)

str.capacity()

max_size()返回理论最⼤可容纳字符数(系统 / 编译器限制)

str.max_size()

2^31-132位系统)

empty()判断是否为空(size() == 0),返回 bool

str.empty()

false

clear( )

清空有效字符(size()0,不释放内存)

str.clear();

str.size()

1.6.5 string的容量与状态查询

string提供多个成员函数查询和控制容量,核⼼包括size()/ length()capacity()max_

size()empty()clear()

1.6.5.1核⼼容量函数对⽐

1.6.5.2关键概念辨析【扩展】

Size vscapacity

size :实际使⽤的字符数(⽤⼾关⼼的⻓度)。

capacity:当前内存已分配的空间(避免频繁扩容),当size 超过 capacity时,

string会⾃动扩容(通常扩容为原容量的 1.5 倍或 2 倍)。

clear ()不释放内存:clear()仅将 size()设为 0capacity()不变,若需释放内存,可结合shrink_to_fit()C++11+):

1.6.6 string的修改操作

string提供 erase()replace()swap()等成员函数修改内容,覆盖删除、替换、交换场 景。

1.6.6.1删除字符:erase(pos, count)

能力:从索引pos 0开始)处,删除count 个字符。

代码⽰例:

重载版本:还⽀持凭借迭代器删除单个字符(如str.erase(str.begin() + 2)删除索引2的字符)

1.6.6.2替换字符:replace(pos, count, new_str)

功能:从索引pos 处,删除 count 个字符,再插⼊new_strnew_str⻓度可与 count 不同)。

stringstr("123456");

str.clear(); // size=0, capacity=6

str.shrink_to_fit(); // capacity变为 0(释放内存)

stringstr4("0123456789abcdef");

cout <<str4 <<endl;

cout <<"size = "<<str4.size() <<",capacity = "<<str4.capacity() <<

endl; // size = 16,capacity = 16

str4.erase(4,8); // 从索引4开始连续删除8个字符

cout <<str4 <<endl;

cout <<"size = "<<str4.size() <<",capacity = "<<str4.capacity() <<

endl; // size = 8,capacity = 16

1.6.6.3交换字符串:swap(s1,s2)

机制:交换两个string对象的内容,效率极⾼(仅交换内部指针和容量,不拷⻉资料)。

代码⽰例:

1.6.7 string的查找与截取

string提供 find()find_last_of()等查找函数,以及substr()截取⼦串,满⾜字符串检索需求。

1.6.7.1查找函数:find() 与 find_last_of()

1)find(sub_str, pos = 0):正向查找

功能:从索引pos (默认 0)开始,查找sub_str(完整匹配)第⼀次出现的位置,返回索引;未找到返回string::npos(静态常量,表⽰⽆效位置)。

// 替换

stringstr5("0123456789abcdef");

cout <<"替换前:" <<str5 <<endl; // 替换前:0123456789abcdef

str5.replace(3,8,"HELLOWORLD"); // 替换后:012HELLOWORLDbcdef

cout <<"替换后:" <<str5 <<endl;

strings1("郭德纲");

strings2("于谦");

cout <<"交换前:" <<s1 <<"" <<s2 <<endl;

swap(s1,s2); // 1种写法

cout <<"交换后:" <<s1 <<"" <<s2 <<endl;

s1.swap(s2); // 2种写法

cout <<"交换后:" <<s1 <<"" <<s2 <<endl;

2)find_last_of(sub_str):反向查找字符集

功能:查找 sub_str中任意⼀个字符最后⼀次出现的位置(⾮完整匹配,⽽是字符集匹配)。

1.6.7.2截取⼦串:substr(pos, count = string::npos)

功能:从索引pos 开始,截取 count 个字符;若 count 未指定或超过剩余字符数,截取

到字符串末尾。

代码⽰例:

// 正向查找,返回第一次出现的位置

strings3("invaid conversion from 'const char*' to 'char*'");

// 1. 从头开始开始查找from

cout <<s3.find("from") <<endl; // 找到返回第一次出现的索引,找不到返回-1

// 2. 从指定索引位置开始查找from

cout <<s3.find("from", 18) <<endl;

// 3. 判断是否找到

if (s3.find("test") != string::npos)

{

cout <<"找到 test" <<endl;

}

else

{

cout <<"未找到 test" <<endl;

}

stringstr("from 123 from 456");

cout <<str.find_last_of("from"); // 'f'/'r'/'o'/'m'最后出现的位置,输

12(第二个 "from"'m'

注意:若 pos 超过 size(),会抛出 out_of_range异常,需确保pos 合法。

1.6.8 string的连接与⽐较

字符串的连接和⽐较是⾼频操作,string⽀持运算符重载与成员函数两种⽅式。

1.6.8.1字符串连接

+运算符:创建新字符串

特性:连接两个字符串,返回新的string对象(原对象不变)

代码⽰例:

缺点:会创建临时对象,频繁连接时效率较低。

append()成员函数:原地追加

// 字符串截取

string s4= "0123456789abcdef";

// 从索引10开始,截取5个字符

string sub= s4.substr(s4.find("a"),5);

cout <<sub <<endl; // 输出:abcde

// 从索引12开始,截取到末尾

string sub2= s4.substr(12);

cout <<sub2 <<endl; // 输出:cdef

// + 字符串拼接

stringss1("西安");

stringss2("粤嵌科技");

string ss3= ss1 + ss2;

string sa= "a", sb = "b", sc = "c";

cout <<ss3 <<" " <<(ss1 + ss2) <<endl; // 输出:西安粤嵌科技 西安粤嵌科技

cout <<(sa + sb + sc) <<endl;

功能:在当前字符串末尾追加内容,直接修改原对象(⽆临时对象,效率⾼)

代码⽰例:

1.6.8.2字符串⽐较

① 运算符重载:直观简洁

⽀持 == != < > <= >= ,按字典序(ASCII 码) ⽐较:

compare()成员函数:灵活精细

功能:返回整数,0 表⽰相等, 正数 表⽰当前字符串⼤,负数 表⽰当前字符串⼩。

代码⽰例:

// append追加

strings11("0123456789abcdef");

strings12("1234");

cout <<"追加前:" <<s11 <<"的大小是:" <<s11.size() <<"" <<s12 <<"

大小是:" <<s12.size() <<endl;

cout <<"追加前容量:" <<s11.capacity() <<endl;

s11.append(s12);

cout <<"追加后:" <<s11 <<"的大小是:" <<s11.size() <<"" <<s12 <<"

大小是:" <<s12.size() <<endl;

cout <<"追加后容量:" <<s11.capacity() <<endl; // 容器超出后,采用二倍扩容

// 关系运算符比较

strings21("abc");

strings22("abc");

cout <<(s21 == s22) <<endl; // 0-不相等,1-相等

cout <<(s21 < s22) <<endl; // 0-不成立,1-成立

cout <<(s21 >= "abd") <<endl; // 0-不成立,1-成立

// compare()比较

strings31("abcdef");

strings32("abc123");

// 1. 完整比较

cout <<s31.compare(s32) <<endl; // 0-相等,大于0-大于,小于0-小于

// 2. 比较子串:s31的前3个字符 vs s32的前三个字符

cout <<s31.compare(0,3,s32,0,3) <<endl;

posted on 2025-12-13 08:30  ljbguanli  阅读(154)  评论(0)    收藏  举报