C++:STL简介和容器string用法篇

C++:STL简介和容器string用法篇

码农世界 2024-05-26 后端 69 次浏览 0个评论

一、STL简介

       STL是C++中的标准模板库(Standard Template Library)的缩写。它是C++标准库的一部分,提供了一系列的数据结构和算法模板,包括各种容器、算法、迭代器、仿函数等,用于简化和加速C++程序的开发过程。STL的设计理念是提供通用、高效的数据结构和算法实现,使得开发者可以更加专注于业务逻辑的实现,提高代码的可读性、可维护性和可移植性。

       STL在C++中有以下几个主要用处:

  1. 提供丰富的数据结构:STL包含了各种常用的容器,如动态数组(vector)、双向链表(list)、映射(map)、集合(set)等。这些数据结构可以满足不同的需求,如存储数据、快速查找、有序存储等。

  2. 实现高效的算法:STL提供了大量的算法模板,包括排序、查找、变换、合并等,这些算法经过了优化和测试,通常具有高效的执行速度和可靠的性能。开发者可以直接使用这些算法,无需自己从头实现,提高了开发效率。

  3. 提供灵活的迭代器:STL中的迭代器提供了一种统一的访问数据结构元素的方式,包括输入迭代器、输出迭代器、正向迭代器、双向迭代器和随机访问迭代器等。开发者可以根据需要选择合适的迭代器类型进行数据遍历和操作。

  4. 支持泛型编程:STL是基于模板的,支持泛型编程。这意味着开发者可以编写通用的代码,适用于不同类型的数据结构和数据类型,提高了代码的复用性和通用性。

  5. 提高代码的可读性和可维护性:STL提供了经过优化和测试的标准化实现,使得代码更加清晰易懂。开发者可以直接使用STL提供的功能模块,避免了重复造轮子的工作,同时也降低了出错的风险,提高了代码的可维护性和可读性。

       综上所述,STL在提高开发效率和代码质量等方面具有很大的作用,是C++程序开发中不可或缺的重要工具。

       STL六大组件:

C++:STL简介和容器string用法篇

       网上有句话说:“不懂STL,不要说你会C++”。STL是C++中的优秀作品,有了它的陪伴,许多底层的数据结构以及算法都不需要自己重新造轮子,使我们能够快速地进行开发。

       我们的STL系列将从容器string部分开始介绍。

二、string类

       标准库类型string表示可变长的字符序列,使用string类型必须首先包含string头文件。作为标准库的一部分,string定义在命名空间std中。

1.定义和初始化string对象

       string是一个类,因此,实例化出string类时,会调用该类的构造函数。string对象也可以使用其他方式来初始化。常用的string对象构造方法有以下几种:

string s1;// 调用默认构造函数,s1是一个空字符串
string s2 = s1;// 调用拷贝构造函数
string s3 = "hello world!"; // 使用字符串初始化s3
string s4(10, 's'); // 使用10个's'字符初始化s4
string s5(s3, 6, 3);// 从第七个字符开始,将3个s3字符串中的字符拷贝到s5中
string s6(s3, 3);// 将前3个s3字符串中的字符拷贝到s6中

       在构造s5的过程中,可以不传第三个参数,那么编译器将会将第三个参数设为string::npos,而string::npos的值为大约42亿,也就是说,编译器会将s3中的从第七个字符开始,拷贝42亿个字符给s5,但是s3显然没有那么多字符。所以当遇到s3字符串的结尾时,编译器将会停止拷贝。那如果第三个参数传的过大,拷贝长度大于从开始到结尾的长度,那也是遇到字符串末尾然后停止拷贝。

       string类中重载了流插入<<、流提取>>操作符,使我们可以像打印、输入int型、char型等内置类型一样打印或输入string型。也重载了内置类型常用的大多数操作符。

2.遍历string对象

       string类中重载了'[]'运算符,使我们可以像遍历字符数组一样遍历string对象。

void test1()// string对象的遍历
{
	string s1("hello world!");
	for (int i = 0; i < s1.size(); i++)
	{
		cout << s1[i] << ' ';
	}
}
int main()
{
	test1();
	return 0;
}

       运行程序,结果如下:

C++:STL简介和容器string用法篇

       也可以将上面的循环换为范围for循环来遍历string对象,使用起来更加方便。

三、string类成员函数

1.容量

(1)size和length

size_t size() const;
size_t length() const;

       string类中有求字符串长度的函数size()和length(),它们的作用相同。调用方法如下:

void test1()
{
	string s1("hello world!");
	string s2("hellohello world!");
	cout << s1.size() < 

       运行程序,结果如下:

C++:STL简介和容器string用法篇

(2)max_size

       string类中的max_size()函数用于求字符串的潜在最大长度。

size_t max_size() const;

       调用该函数之后,会得到一个非常大的数字。

(3)resize

void resize (size_t n);
void resize (size_t n, char c);

       string类中提供了两个调节字符串大小的函数。第一个参数都是一个无符号整形,意思是将字符串大小调整为n。若字符串长度大于n,那么n之后的字符将会丢弃,若字符串的长度小于n,那么第一个函数将会在n之后填充空字符,第二个函数则会使用指定的字符填充。

       我们知道,字符串末尾还隐藏了一个‘\0’字符。空字符是不计入长度的。计算字符串长度时,遇到任意空字符就停止计数。打印的时候也是以任意空字符为结尾的。

void test1()
{
	string s1("hello\0\0\0\0\0 world!    ");
	string s2("hellohello world!");
	//s1.resize(18);
	cout << s1 << 'a' << endl;
	cout << s1.size() << endl;
	
}

       运行程序,结果如下:

C++:STL简介和容器string用法篇

       但是我们将resize函数取消注释,再次运行程序:

C++:STL简介和容器string用法篇

       发现长度来到了18,也就是说,编译器填充的空字符,是计入长度的。

C++:STL简介和容器string用法篇

C++:STL简介和容器string用法篇

       通过监视窗口我们看到,没有执行resize语句时,s1中字符串只有五个字符,执行之后,后面13个字符都是\0并且计入长度。

(4)capacity

size_t capacity() const;

       string类中有计算容量的成员函数,它表示编译器为对象实际分配的内存空间,它可以大于或等于字符串的长度。若容量满时,会自动扩容。

(5)reverse

void reserve (size_t n = 0);

       reverse函数使用来修改字符串容量的。给reverse传的参数n是告诉编译器假定字符串的长度为n,然后让编译器重新为对象分配空间。编译器会结合实际字符串长度来分配空间。若n小于实际字符串长度,容量的变化具体看编译器。

(6)clear

void clear();

       它的作用为清空字符串。使对象变为长度为0的字符串。

(7)empty

bool empty() const;

       它的作用是判断字符串是否为空,并不会改变字符串中的内容。

(8)shrink_to_fit

bool empty() const;

       请求字符串减小其容量以适应其大小。

2.元素访问

(1)operator[]

       string类中具有运算符重载, 使我们可以像访问数组那样访问string对象中的值。

char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;

(2)at

char& at (size_t pos);
const char& at (size_t pos) const;

       返回对字符串中位置pos处的字符的引用。

(3)back

char& back();
const char& back() const;

       返回对字符串最后一个字符的引用。此函数不应在空字符串上调用。

(4)front

char& front();
const char& front() const;

       返回对字符串第一个字符的引用。此函数不应在空字符串上调用。

3.修改

(1)operator+=

string& operator+= (const string& str);
string& operator+= (const char* s);
string& operator+= (char c);

       string具有+=重载函数,使我们可以像内置类型一样使用+=操作符:

void test1()
{
	string s1("hello world!");
	string s2("hi");
	s1 += "sss";
	s1 += 'a';
	s1 += s2;
	cout << s1 << endl;
	cout << s1.size() << endl;
}

       运行代码,结果如图所示:

C++:STL简介和容器string用法篇

       有了+=重载操作符重载,我们可以很方便地为字符串后添加字符。

(2)append

string& append (const string& str);
string& append (const string& str, size_t subpos, size_t sublen);
string& append (const char* s);
string& append (const char* s, size_t n);
string& append (size_t n, char c);
template 
string& append (InputIterator first, InputIterator last);

       append也表示向字符串的末尾添加字符串。它重载了许多函数,实现了很多功能。

string& append (const string& str);

       表示向一个string对象末尾添加另一个string对象,也就是在一个字符串的末尾添加另一串字符串。

string& append (const string& str, size_t subpos, size_t sublen);

       表示向一个string对象末尾添加另一个string对象的一部分,它从subpos位置开始,直到拷贝长度达到sublen时为止或者直到遇到字符串末尾。

string& append (const char* s);

       表示向string对象末尾附加一个由指针变量指向的字符串。

string& append (const char* s, size_t n);

       表示向string对象末尾附加一个由指针变量指向的字符串的前n个字符。

string& append (size_t n, char c);

       表示向string对象末尾附加n个c字符。

(3)push_back

void push_back (char c);

       表示向string对象末尾附加1个c字符。

(4)assign

string& assign (const string& str);
string& assign (const string& str, size_t subpos, size_t sublen);
string& assign (const char* s);
string& assign (const char* s, size_t n);
string& assign (size_t n, char c);

        assign表示赋值,将当前值清空并赋新值。

string& assign (const string& str);

       表示将另一个string对象赋给当前string对象。

string& assign (const string& str, size_t subpos, size_t sublen);

       表示将另一个string对象的一部分赋给当前string对象。从subpos开始,到sublen处结束,或遇到字符串尾结束。

string& assign (const char* s);

       表示将s指向的字符串赋给当前string对象。

string& assign (const char* s, size_t n);

        表示将s指向的字符串的前n个字符赋给当前string对象。

string& assign (size_t n, char c);

       表示将n个c字符赋给当前string对象。

(5)insert

 string& insert (size_t pos, const string& str);
 string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);
 string& insert (size_t pos, const char* s);
 string& insert (size_t pos, const char* s, size_t n);
 string& insert (size_t pos, size_t n, char c);
void insert (iterator p, size_t n, char c);

        insert也表示插入,它支持在任意位置插入。不过它的效率不高。

string& insert (size_t pos, const string& str);

       表示在下标pos之后插入一个string对象。

string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);

       表示在下标pos之后插入一个string对象的一部分,它从subpos处开始,直到拷贝长度达到sublen或者遇到字符串结尾。

string& insert (size_t pos, const char* s);

       表示在pos位置插入一个s指向的字符串。

string& insert (size_t pos, const char* s, size_t n);

       表示在pos位置插入一个s指向的字符串的前n个字符。

string& insert (size_t pos, size_t n, char c);

        表示在pos位置插入n个字符c。

(6)erase

string& erase (size_t pos = 0, size_t len = npos);

       erase表示删除,删除从pos位置开始, 直到删除长度达到len或者对象中已经无字符。若不传参数,那么表示全部删除。

(7)replace

string& replace (size_t pos,  size_t len,  const string& str);
string& replace (size_t pos,  size_t len,  const string& str,
                 size_t subpos, size_t sublen);
string& replace (size_t pos,  size_t len,  const char* s);
string& replace (size_t pos,  size_t len,  const char* s, size_t n);
string& replace (size_t pos,  size_t len,  size_t n, char c);

       replace表示替换。

string& replace (size_t pos,  size_t len,  const string& str);

       表示从下标pos位置开始,len长度的字符替换为另一个string对象中的字符串。

string& replace (size_t pos,  size_t len,  const string& str,
                 size_t subpos, size_t sublen);

       表示从下标pos位置开始,len长度的字符替换为另一个string对象中的字符串的一部分,从小标subpos位置开始,拷贝sublen长度的字符串或遇到字符串末尾。

string& replace (size_t pos,  size_t len,  const char* s);

       表示从下标pos位置开始,len长度的字符替换为s指向的字符串。

string& replace (size_t pos,  size_t len,  const char* s, size_t n);

       表示从下标pos位置开始,len长度的字符替换为s指向的字符串的前n个字符。

string& replace (size_t pos,  size_t len,  size_t n, char c);

       表示从下标pos位置开始,len长度的字符替换为n个c字符。

(8)swap

void swap (string& str);
void swap (string& x, string& y);

       交换两string对象的值。

void test1()
{
	string s1("hello world!");
	string s2("abcdefg");
	s1.swap(s2);
	cout << s1 << endl;
	cout << s2 << endl;
}

       运行代码,结果如下图所示:

C++:STL简介和容器string用法篇

(9)pop_back

void pop_back();

       尾部删除一个字符。

(10)getline

istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);

       从流中提取一行字符串到string对象中,直到遇到delim(界定字符)或换行符。若指定了界定字符,那么当输入界定字符之后,编译器会只保留界定字符之前的字符,将string对象存储的值删除,并添加上新输入的字符。若没有指定界定字符,那么当遇到换行符时,即代表输入结束。

4.字符串操作

(1)c_str

const char* c_str() const;

       返回一个字符串指针,指向一块存储着C风格字符串的空间。字符串的末尾附加了一个空字符。

(2)data

const char* data() const;

       返回一个字符串指针,指向一块存储着C风格字符串的空间。在C++11之前,该字符串末尾不附加空字符,C++11之后,附加了一个空字符,执行与c_str一样的操作。

(3)copy

size_t copy (char* s, size_t len, size_t pos = 0) const;

       从pos位置开始,拷贝len个长度的字符到s指向的空间中。返回拷贝字符的个数。

(4)find

size_t find (const string& str, size_t pos = 0) const;
size_t find (const char* s, size_t pos = 0) const;
size_t find (const char* s, size_t pos, size_type n) const;
size_t find (char c, size_t pos = 0) const;

       第一个重载成员函数可以查找子字符串,pos是开始查找的位置。若找到则返回子字符串在字符串中的下标,若找不到则返回nops。

       第二个重载成员函数可以查找s指向的字符串。

       第三个重载成员函数可以查找s指向的字符串,第三个参数n是查找的长度,若小于被查找的字符串长度,则查找前n个字符组成的字符串。

       第四个重载成员函数可以查找指定的字符。

(5)rfind

size_t rfind (const string& str, size_t pos = npos) const;
size_t rfind (const char* s, size_t pos = npos) const;
size_t rfind (const char* s, size_t pos, size_t n) const;
size_t rfind (char c, size_t pos = npos) const;

       查找要查找的对象最后一次出现的位置。

(6)find_first_of

size_t find_first_of (const string& str, size_t pos = 0) const;
size_t find_first_of (const char* s, size_t pos = 0) const;
size_t find_first_of (const char* s, size_t pos, size_t n) const;
size_t find_first_of (char c, size_t pos = 0) const;

       在string对象中查找一个字符,它同时出现在另一个对象中并且在string对象中是第一个这样的字符。返回该字符的下标。支持查找另一个string对象、指针指向的空间,单个字符。

size_t find_last_of (const string& str, size_t pos = npos) const;
size_t find_last_of (const char* s, size_t pos = npos) const;
size_t find_last_of (const char* s, size_t pos, size_t n) const;
size_t find_last_of (char c, size_t pos = npos) const;

       在string对象中查找一个字符,它同时出现在另一个对象中并且在string对象中是最后一个这样的字符。

(7)find_first_not_of

size_t find_first_not_of (const string& str, size_t pos = 0) const;
size_t find_first_not_of (const char* s, size_t pos = 0) const;
size_t find_first_not_of (const char* s, size_t pos, size_t n) const;
size_t find_first_not_of (char c, size_t pos = 0) const;

       在string对象中查找一个字符,它在另一个对象中不存在,并且是第一个这样的字符,返回该字符的下标。

(8)find_last_not_of

size_t find_last_not_of (const string& str, size_t pos = npos) const;
size_t find_last_not_of (const char* s, size_t pos = npos) const;
size_t find_last_not_of (const char* s, size_t pos, size_t n) const;
size_t find_last_not_of (char c, size_t pos = npos) const;

       在string对象中查找一个字符,它在另一个对象中不存在,并且是最后一个这样的字符,返回该字符的下标。

(9)substr

string substr (size_t pos = 0, size_t len = npos) const;

       创建一个子字符串,该子字符串的值为string对象中从pos位置开始,len个长度或到达字符串末尾的字符串的拷贝。

(10)compare

int compare (const string& str) const;
int compare (size_t pos, size_t len, const string& str) const;
int compare (size_t pos, size_t len, const string& str,
             size_t subpos, size_t sublen) const;
int compare (const char* s) const;
int compare (size_t pos, size_t len, const char* s) const;
int compare (size_t pos, size_t len, const char* s, size_t n) const;

       将字符串的值与参数指定的字符串的值进行比较。

       返回值:

  • =0,两字符串相等。
  • >0,string对象1>string对象2。若遇到第一个字符串与第二个字符串不相等的第一个字符,比较它们的ascii值。
  • <0,string对象1int compare (size_t pos, size_t len, const string& str) const;

       将string对象中从pos位置开始,len个长度的字符串与另一个对象比较。

int compare (size_t pos, size_t len, const string& str,
             size_t subpos, size_t sublen) const;

       将string对象中从pos位置开始,len个长度的字符串与另一个对象中的subpos位置开始,sublen长度的字符串比较。

转载请注明来自码农世界,本文标题:《C++:STL简介和容器string用法篇》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,69人围观)参与讨论

还没有评论,来说两句吧...

Top