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++知识库 -> C++ string类 -> 正文阅读

[C++知识库]C++ string类

string类是由头文件string支持的(注意,头文件string.h和cstring支持对C-风格字符串进行操纵的C库字符串函数,但不支持string类)。string类位于名称空间std中,因此必须提供using编译指令或使用std::string来引用它。

//string 实际上是模板具体化 basic_string<char> 的一个 typedef
//即由于含有 typedef basic_string<char> string; 这条语句,string 类成为了basic_string<char>的一个别名
//string 库实际上是基于一个模板类的:
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
basic_string {......};

//模板 basic_string 有4个具体化,每个具体化都有一个 typedef 名称:
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
typedef basic_string<char16_t> u16string;//C++11
typedef basic_string<char32_t> u32string;//C++11
//C++ primer plus P539 有详细解释

//size_type 是一个依赖于实现的整型,是在头文件 string 中定义的
//string 类将 string::npos 定义为字符串的最大长度,通常为 unsigned int 的最大值

一、string类构造函数

string(const char* s);//将 string 对象初始化为 s 指向的C-风格字符串

string(size_type n, char c);//创建一个包含 n 个元素的 string 对象,其中每个元素都被初始化为字符 c

string(const string& str);//复制构造函数

string();//创建一个默认的 string 对象,长度为0(默认构造函数)

string(const char* s, size_type n);//将一个 string 对象初始化为 s 指向的字符串的前 n 个字符,即使超过了字符串的结尾
//即 n 大于字符串长度,在这种情况下,将会导致字符串 s 后面的无用内存被复制到 string 对象中

template<class Iter>
string(Iter begin, Iter end);//将 string 对象初始化为区间 [begin, end) 内的字符,其中 begin 和 end 的行为就像指针,用于指定位置,范围包括 begin 在内,但不包括 end .
//begin 和 end 可以使指针,指向内存中的两个位置,也可以是迭代器————广泛应用于 STL 中的广义化指针

string(const string& str, size_type pos = 0, size_type n = npos);//将一个 string 对象初始化为对象 str 中从位置 pos 开始到结尾的字符,或从 pos 开始的 n 个字符

string(string&& str);//C++11新增

string(initializer_list<char> il);//C++11新增,让使用者能够将列表初始化用于 string 类

使用构造函数的实例:

#include <iostream>
#include <string>

//标号1至6表示使用的构造函数的编号

int main() {
	using namespace std;
	string one("Lottery Winnner!");//use 1
	cout << one << endl;//重载的 << 运算符
	string two(20, '$');//use 2
	cout << two << endl;
	string three(one);//use 3
	cout << three << endl;
	one += " Oops!";//重载的 += 运算符
	cout << one << endl;
	two = "Sorry! That was ";//重载的 = 运算符
	three[0] = 'P';//重载的 [] 运算符
	string four;//use 4
	four = two + three;//重载的 + 和 = 运算符
	cout << four << endl;
	char alls[] = "All's well that ends well";
	string five(alls, 20);//use 5 
//如果用40代替20,将导致15个无用的字符被复制到 five 的结尾处,即构造函数将内存中位于字符串"All's well that ends well"后面的内容作为字符
	cout << five << "!\n";
	string six(alls + 6, alls + 10);//use 6
	cout << six << ", ";
	string seven(&five[6], &five[10]);//use 6,此处不能用 five + 6 和 five + 10,因为对象名(不同于数组名)不会被看做是对象的地址,所以 five + 6 是没有意义的
										//然而,five[6] 是一个 char 值,所以 &five[6] 是一个地址,因此可以被用作该构造函数的一个参数	
	cout << seven << "...\n";
	string eight(four, 7, 16);//use 7,从 four 的第8个字符(位置7)开始,将16个字符复制到 eight 中
	cout << eight << " in motion!" << endl;
	string a;//诸如 string a('n'); string a = 'n'; 之类的初始化语句是不被允许的
	a = 'n';//a 中包含一个字符 n, 可以用字符来给 string 类对象赋值,但不能用字符初始化 string 类
	return 0;
}

运行结果:

二、string类的赋值和比较和连接

= //用与赋值,第二个操作数可以是 string 类对象, 字符串或单个字符
+= //用于连接加赋值,第二个操作数可以是 string 类对象, 字符串或单个字符
+ //用于连接,可以是 string 类与 string 类相加、 string 类与字符串相加、 string 类与字符相加
>
<
>=
<=
==  //只有当两者的字符数、每个位置对应的字符都相等时,等号才成立
!=  //以上关系运算符的返回值都是 bool 类型,成立则返回 true,否则返回 false

//以上运算符都经过多次重载,使之可以应用于不同的情况


//还可以用 assign 函数对 string 类赋值(assign 为公有成员函数)
//需要注意的是 assign 函数相当于 = ,只不过功能更强大,所以使用 assign 函数是给原 string 对象赋一个新的值,而不是对原 string 对象的一部分做改变

string& assign (const string& str);//复制字符串,与 = 作用相同

string& assign (const string& str, size_t subpos, size_t sublen);//从 str 下标为 subpos (即第 subpos + 1 个元素) 的字符开始复制 sublen 个字符
//即复制下标为 [subpos, subpos + sublen) 的部分,当 subpos + sublen 超过了 str 的最大下标时,则复制到 str 结尾停止

string& assign (const char* s);

string& assign (const char* s, size_t n);//复制 s 所指向的字符串的前 n 个字符

string& assign (size_t n, char c);//用字符 c 的 n 个连续副本替换当前值

template <class InputIterator>
string& assign (InputIterator first, InputIterator last);//first 和 last 的含义与构造函数6的 begin 和 end 相同,复制 [first, last) 之间的字符

string& assign (initializer_list<char> il);//C++11

string& assign (string&& str) noexcept;//C++11



//append 成员函数也可以用于字符串之间的连接,类似于 + 号,这里就不细说了,上几个例子

string s1("good"),s2("morning!");
s1.append(s2);//将 s2 添加到 s1 的末尾
cout << s1;
s2.append(s1, 3, s1.size());//将 s1 中下标为3开始的 s1.size() 个字符添加到 s2 末尾
//如果字符串内没有足够字符,则复制到字符串最后一个字符
cout << s2;


//也可以用成员函数 compare 比较 string 大小(相等返回0,前者大于后者返回1,否则返回-1)

string s1("hello"),s2("hello"),s3("hell");
int f1 = s1.compare(s2);
int f2 = s1.compare(s3);
int f3 = s3.compare(s1);
int f4 = s1.compare(1,2,s3,0,3); //拿 s1 下标为1开始的2个字符与 s3 下标为0开始的3个字符作比较
intf5 = s1.compare(0,s1.size(),s3);//拿 s1 下标为0开始的 s1.size() 个字符与 s3作比较
cout << f1 << endl << f2 << endl << f3 <<endl;
cout << f4 << endl << f5 << endl;

//输出:
0  // hello == hello
1  // hello > hell
-1 // hell < hello
-1 // el< hell
1  // hello > hell


assign 实例:

#include <iostream>
#include <string>
using namespace std;

int main() {
	string base("hello world!");
	string str;
	str.assign(base);//use 1
	cout << str << endl;
	str.assign(base, 0, 4);//use 2
	cout << str << endl;
	const char* s = "PHP is the best language!";
	str.assign(s);//use 3
	cout << str << endl;
	str.assign(s, 5);//use 4
	cout << str << endl;
	str.assign(5, '*');//use 5
	cout << str << endl;
	str.assign(base.begin() + 2, base.begin() + 7);//use 6
	cout << str << endl;
	str.assign(s + 11, s + 24);//use 6
	cout << str << endl;
	str.assign(s, 0, 3);//这里顺便提一句,查资料的时候没看到过这个函数,但是却可以使用
	//我猜测可能是 string 中的构造函数将 const char* 隐式转化为 string 类对象了
	cout << str << endl;
	return 0;
}

运行结果:

?三、访问string对象的单个字符和string对象的长度

方法一:用重载的 [] 符号访问

方法二:用成员函数 at() 访问(和用 [] 访问的效果相同)

eg:
string s1("Hello");
for(int i = 0; i<s1.lenth(); i++)
    cout << s1.at(i) << endl;

//at() 和 [] 的差别在于 成员函数 at() 会做范围检查,如果超出范围,会抛出 out_of_range 异常,而下标运算符 [] 不做范围检查。
//当然作为代价,用 at() 成员函数的效率会比 [] 低一点

//string 类有两个成员函数 size() 和 lenth(),它们的作用相同,都返回 string 对象中包含的字符数
//为什么这两个函数完成相同的任务呢? 
//lenth() 成员函数来自较早版本的 string 类,而 size() 则是为提供 STL 兼容性而添加的

四、string类的find成员函数

//npos 变量是 string 类的静态成员,它的值是 string 对象能存储的最大字符数。由于索引从0开始,所以它比最大的索引值大1,因此可以使用它来表示没有查找到字符或字符串


size_type find(const string& str, size_type pos = 0) const ;
//从字符串下标为 pos 的地方开始查找子串 str。如果找到,则返回该子字符串首次出现时其首字符的索引;否则。返回 string::npos

size_type find(const char* s, size_type pos = 0) const ;//同上

size_type find(const char* s, size_type pos, size_type n);
//从字符串的 pos 位置开始,查找 s 的前 n 个字符组成的子字符串

size_type find(char ch, size_type pos = 0) const ;
//从字符串的 pos 位置开始,查找字符 ch


//string 库还提供相关方法: rfind(), find_first_of(), find_last_of(), find_first_not_of() 和 find_last_not_of(),他们的重载函数特征标都与 find() 方法相同。

string s1("hello worldlo");

rfind() //查找子字符串或字符最后一次出现的位置(即从后往前找字符串或字符第一次出现的地方)
s1.rfind("lo"); //返回11

find_first_of() //在字符串中查找参数中任何一个字符首次出现的位置
s1.find_first_of("abcde"); //返回1,e 为字符串中首次出现的参数中的字符

find_last_of() //在字符串中查找参数中任何一个字符最后一次出现的地方(从后往前找第一次出现的地方)
s1.find_last_of("abcde"); //返回10

find_first_not_of() //在 s1 中从前向后查找不在参数中的字符第一次出现的地方
s1.find_first_not_of("abcdeh"); //返回2

find_last_not_of() //从后往前找不在参数中的字符第一次出现的地方
s1.find_last_not_of("abcdeol");//返回8


//以上函数在没有找到目标值的情况下都返回 string::npos

五、string对象的其它方法

string s1("hello world"),s2("I love C++");//下面语句都默认 s1 s2 处于初始状态


//求 string 类的子串,substr 成员函数
s2 = s1.substr(4, 5);//将 s1 从下标4开始的5个字符赋给 s2,若长度超过 s1 最大下标,则到 s1 结尾停止


//交换两个 string 对象,swap 成员函数
s1.swap(s2);//交换 s1 和 s2


//删除 string 中的字符, erase 成员函数
1.删除指定位置的字符
erase()函数用于删除指定位置字符的格式为
iterator erase (iterator p);
//其中,参数iterator是迭代器,即删除迭代器p指向的字符。返回值为删除后的字符串。
s1.erase(s1.begin()+2);//执行该语句后 s1 为 "helo world"

2.删除指定长度的字符串
erase() 函数用于删除指定长度字符串的格式为
string& erase(size_t pos=0, size_t len = npos);//删除从下标 pos 开始(包含 pos),长度为 len 的字符串
//其中,参数 pos 表示要删除字符串的起始位置,其默认值是0;len 表示要删除字符串的长度,其默认值是string::npos。返回值是删除后的字符串。
s1.erase(4);//执行该语句后 s1 为 "hell"
s2.erase(2, 6);//执行该语句后 s2 为 "I ++"

3.删除指定范围的字符串
erase() 函数用于删除指定范围字符串的格式为
iterator erase (iterator first, iterator last);
//其中,first和last分别表示范围的起点和终点。需要注意的是,该范围包含first,但是不包含last,即该范围是 [first, last)。erase() 函数的返回值是删除后的字符串。
s1.erase(s1.begin()+4, s1.begin()+8);//执行该语句后 s1 为 "hellrld"


//替换 string 中的字符串,replace 成员函数
s1.replace(2, 3, "haha");//将 s1 中下标2开始的3个字符换成 "haha",执行该语句后 s1 为 "hehaha world"
s2.replace(2, 3, "haha", 1, 2);//将 s2 中下标2开始的3个字符换成 "haha" 中下标1开始的2个字符
//执行后 s2 为 "I ahe C++"


//在 string 中插入字符,insert 成员函数
s1.insert(5, s2);//将 s2 插入 s1 下标为5的位置(即插到 s1 中第5个字符的后面)
//s1 现在为 "helloI love C++ world"
s1.insert(2, s2, 5, 3);//将 s2 中下标5开始的3个字符插入 s1 下标2的位置
//s1 现在为 "hee Cllo world"


//转换成 C 语言式 char* 字符串,c_str() 和 data() 成员函数
s1.c_str();//返回传统的 const char* 字符串,且该字符串以 '\0' 结尾 
//文件操作用open成员函数打开文件时,参数必须为 C 风格字符串,而不能是 string 类对象,可用该函数将 string 类对象转化成 C 风格字符串
s1.data();//返回一个 char* 类型的字符串

replace成员函数的详细用法

insert成员函数的详细用法

六、字符串的流处理

除了标准流和文件流输入输出外,还可以从string进行输入输出;
类似istream和ostream进行标准流输入输出,我们用istringstream和ostringstream进行字符串上的输入输出,也称为内存输入输出。
?

#include <iostream>
#include <string>
#include <sstream>//字符串输入输出流头文件
using namespace std;

int main() {
	string input("Input test 123 4.7 A");
	istringstream inputString(input);
	string string1, string2;
	int i;
	double d;
	char c;
	inputString >> string1 >> string2 >> i >> d >> c;
	cout << string1 << endl << string2 << endl;
	cout << i << endl << d << endl << c << endl;
	long L;
	if (inputString >> L) cout << "long\n";
	else cout << "empty\n";
	ostringstream outputString;
	int a = 10;
	outputString << "This " << a << " ok" << endl;//这一步相当于将这些字符串放入到字符串输出流里面
	cout << outputString.str();//用 str() 成员函数将字符串从流里面取出来
	return 0;
}

运行结果:

?字符串的流处理详细解释???????

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-16 11:33:49  更:2021-08-16 11:33:56 
 
开发: 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年5日历 -2024/5/20 3:53:16-

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