Bootstrap

C++详细笔记(六)string库

1.介绍STL库

C++ STL(Standard Template Library,标准模板库)是 C++ 标准库的一部分,它提供了一系列通用的模板类和函数,大大方便了 C++ 程序员的开发工作

优点

  1. 代码复用性高:可以直接使用 STL 中的容器、算法和迭代器,避免了重复开发相同功能的代码。例如,在处理数据集合时,不用自己去实现一个复杂的动态数组或者排序算法,直接使用 vector 和 sort 即可。
  2. 效率高:STL 的实现经过了高度优化。例如,容器的内存管理和算法的时间复杂度都经过精心设计。像关联容器(set、map)基于红黑树的实现,保证了插入、删除和查找操作在对数时间内完成。
  3. 通用性强:可以用于各种不同类型的数据,只要数据类型支持相应的操作(如比较操作等)。例如,std::sort可以对内置类型(如 int、double 等)的数组进行排序,也可以对自定义类的数组进行排序,只要自定义类重载了比较运算符。

2.string库

1.std::string::begin/end

beginend函数用于获取指向字符串中字符范围的迭代器。begin返回一个指向字符串第一个字符的迭代器,end返回一个指向字符串最后一个字符之后位置的迭代器,其范围同样是左闭右开区间[begin, end)

#include <iostream>
#include <string>
using namespace std;
//std::string::begin/end//为首元素和尾元素的地址。
int main()
{
	string str("Hello world");
	for (string::iterator i = str.begin(); i != str.end(); ++i)
	{
		cout << *i;
	}
	cout << endl;
		return 0;
}

2.std::string:: size, length, capacity and max_size

  • std::string中,sizelength函数的功能是完全相同的。它们都返回字符串中当前字符的数量。capacity函数返回当前为字符串分配的存储空间能够容纳的字符数量。这个容量通常会大于或等于字符串的长度(size)。当向字符串中添加字符时,如果新的长度超过了当前的容量,std::string会自动重新分配足够的内存来容纳新的字符。max_size函数返回std::string类型的对象理论上能够容纳的最大字符数量。这个限制通常是由系统的资源(如内存大小、地址空间等)或者库的实现所决定的。实际上,达到这个最大尺寸是非常罕见的情况。
int main()
{
	string str("Hello world");
	cout << "size: " << str.size() << "\n";
	cout << "length: " << str.length() << "\n";
	cout << "capacity: " << str.capacity() << "\n";
	cout << "max_size: " << str.max_size() << "\n";
	return 0;
}

3.std::string::swap

它的主要功能是交换两个std::string对象的内容。这包括字符串中的字符序列、字符串的长度以及字符串的容量等所有相关属性。

int main()
{
	string str1("Hello world");
	string str2("Hello bit");
	cout << "str1:" <<str1<< endl;
	cout << "str2:" <<str2<<endl;
	str2.swap(str1);
	cout << "str1:" <<str1<< endl;
	cout << "str2:" <<str2<< endl;

	return 0;
}

4. std::string::clear

它的主要作用是将字符串清空,即将字符串中的所有字符移除,使得字符串的长度(size)变为 0。不过,这个操作通常不会改变字符串的容量(capacity),字符串对象所占用的内存空间可能不会立即释放,而是在后续适当的时候由内存管理机制处理。

int main()
{
	string std("Hello world");
	cout << std << endl;
	std. clear();
	cout << std << endl;
	return 0;
}

5.std::string::cbegin / cend

cbegin它返回一个指向字符串第一个字符的常量迭代器(const_iterator)。这个迭代器用于遍历字符串中的字符,但不允许通过该迭代器修改字符串中的字符。这在处理常量字符串或者不希望在遍历过程中意外修改字符串内容的场景中非常有用。cend和cbegin一起,它们定义了一个左闭右开的区间[cbegin, cend),用于遍历字符串中的字符。这种区间表示方式在 C++ 的 STL(标准模板库)中是很常见的,方便了许多基于范围的算法的实现。

int main()
{
	string str("Hello world");
	for (auto i = str.cbegin(); i != str.cend(); i++)
		cout << *i;
	cout << endl;
	return 0;
}

6.std::string::rbegin /rend

std::string::rbeginstd::string类的一个成员函数,它返回一个反向迭代器,指向字符串的最后一个字符。这个反向迭代器允许你从字符串的末尾开始向开头遍历。它与普通迭代器(如begin)的遍历方向相反。std::string::rend返回一个反向迭代器,指向字符串第一个字符之前的位置。rbeginrend一起定义了一个左闭右开的区间[rbegin, rend),用于反向遍历字符串中的字符。

int main()
{
	string str("dlrow olleH");
	for (string::reverse_iterator ri = str.rbegin(); ri != str.rend(); ri++)
		cout << *ri;
	cout << endl;
	return 0;
}

7.std::string::compare

它有多种重载形式,比较的方式可以是和另一个std::string对象比较,也可以是和 C - 风格字符串(以null结尾的字符数组)比较。

  • 基本的调用形式为int compare(const std::string& str) const,这里str是要与之比较的另一个std::string对象。它返回一个整数值来表示比较的结果:
    • 如果当前字符串小于str,返回一个小于 0 的值。
    • 如果当前字符串等于str,返回 0。
    • 如果当前字符串大于str,返回一个大于 0 的值。
int main()
{
    std::string str1("green apple");
    std::string str2("red apple");

    if (str1.compare(str2) != 0)
        std::cout << str1 << " is not " << str2 << '\n';

    if (str1.compare(6, 5, "apple") == 0)
        std::cout << "still, " << str1 << " is an apple\n";

    if (str2.compare(str2.size() - 5, 5, "apple") == 0)
        std::cout << "and " << str2 << " is also an apple\n";

    if (str1.compare(6, 5, str2, 4, 5) == 0)
        std::cout << "therefore, both are apples\n";

    return 0;
}



int main()
{
    string str1("Hello world");
    string str2("Hello bit");
    if (str1.compare(str2) != 0)
    {
        cout << str1 << " is not " << str2 << endl;
    }
    if (str1.compare(0, 5, "Hello") == 0)
    {
        cout << "This is Hell0" << endl;
    }
    if (str1.compare(0, 5, str2, 0, 5) == 0)
    {
        cout << "OK They both have Hello" << endl;
    }
    if (str1.compare(str1.size() - 6, 5, "world"))
    {
        cout << "This is world" << endl;
    }
    return 0;

}

8.std::string::replace

函数用于替换字符串中的部分内容。它有多种重载形式,以适应不同的替换需求。常见的一种形式是string& replace (size_t pos, size_t len, const string& str);,其中pos表示起始位置,len表示要替换的长度,str是用于替换的字符串。它会将当前字符串中从pos位置开始、长度为len的子串替换为str

int main()
{
	string str1("Hello world");
	string str2 = "Hello";
	string str3("world");
	string str4 = "Hello bit";
	cout << str1 << endl;
	str1.replace(6, 5, str2);
	cout << str1 << endl;
	cout << str1 << endl;
	str1.replace(0,9, str4);
	cout << str1 << endl;
	cout << str1 << endl;
	str1.replace(6, 5, "bit");
	cout << str1 << endl;
	cout << str1 << endl;
	str1.replace(str1.begin(), str1.end(), str4);
	cout << str1 << endl;
	cout << str1 << endl;
	str1.replace(str1.begin()+6, str1.end(), str4.begin()+6,str4.end());
	cout << str1 << endl;
	cout << str2 << endl;
	str2.replace(5, 5, str3);
	cout << str2 << endl;
}

9.std::string::reserve

它的主要功能是为字符串预留足够的存储空间,以容纳一定数量的字符。这个函数的参数是一个无符号整数n,表示要预留的字符数量。调用reserve函数后,字符串的容量(capacity)至少会增加到n(如果当前容量小于n),但字符串的长度(size)不会改变,也就是说,预留空间不会影响字符串中已有的字符内容。

#include <iostream>
#include <fstream>
#include <string>

int main()
{
	std::string str;

	std::ifstream file("test.txt", std::ios::in | std::ios::ate);
	if (file) {
		std::ifstream::streampos filesize = file.tellg();
		str.reserve(filesize);

		file.seekg(0);
		while (!file.eof())
		{
			str += file.get();
		}
		std::cout << str;
	}
	return 0;
}



#include <iostream
#include <string>
#include <algorithm>
int main() {
    std::string str;
    // 预留空间为10个字符
    str.reserve(20 );
    std::cout << "初始容量: " << str.capacity() << std::endl;
    // 向字符串中添加字符
    for (char c = 'a'; c <= 'z'; ++c) {
        if (str.capacity() - str.size() > 0) {
            str.push_back(c);
        }
        else {
            std::cout << "需要重新分配内存了" << std::endl;
            break;
        }
    }
    std::cout << "添加字符后的字符串: " << str << std::endl;
    std::cout << "当前容量: " << str.capacity() << std::endl;
    return 0;
}

10.std::string::append

函数用于将一个字符串或字符序列添加到现有字符串的末尾。它有多种重载形式,以适应不同类型的参数。

#include <iostream>
#include <string>

int main()
{
    std::string str;
    std::string str2 = "Writing ";
    std::string str3 = "print 10 and then 5 more";

    // used in the same order as described above:
    str.append(str2);                       // "Writing "
    str.append(str3, 6, 3);                   // "10 "
    str.append("dots are cool", 5);          // "dots "
    str.append("here: ");                   // "here: "
    str.append(10u, '.');                    // ".........."
    str.append(str3.begin() + 8, str3.end());  // " and then 5 more"
    //str.append<int>(5, 0x2E);                // "....."
    std::cout << str << '\n';
    return 0;
}


#include <iostream>
#include <string>
using namespace std;
int main()
{
    string str;
    string str1("Hello");
    string str2 = "World";
    string str3("Hello Bit");
    cout << str << endl;
    str.append(str1);
    cout << str << endl;
    str.append(" ");
    str.append(str2);
    cout << str << endl;
    str.append(" ",1);//输出空格的字符,且输出一个
    str.append("and go go go", 4);
    str.append(str3, 6, 3);
    cout << str << endl;
    return 0;
}

11.std::string::assign

主要用于将一个新的字符串内容赋给当前字符串对象。它有多种重载形式,可以接受不同类型的参数来实现赋值操作。

#include <iostream>
#include <string>
using namespace std;
int main()
{
	string str;
	string str1("Hello wrold");
	string str2("Hello bit");
	cout << str << endl;
	str.assign(str2);
	cout << str << endl;
	str.assign(str1, 6);//替换之后是world不是Hello world由此可见assign与replace的区别是assign会把之前的全部删除之后再进行复制粘贴。
	cout << str << endl;
	str.assign(str1);
	cout << str << endl;
	return 0;


}

12.std::string::copy

用于将字符串中的字符复制到一个字符数组中。它的函数原型为size_t copy(char* s, size_t len, size_t pos = 0) const;。其中,s是目标字符数组的指针,len是要复制的最大字符数,pos是从字符串的哪个位置开始复制(默认是 0,即从字符串开头复制)。该函数返回实际复制的字符数量。需要注意的是,copy函数不会自动在目标字符数组末尾添加'\0'

#include <iostream>
#include <string>

int main()
{
	char buffer[20];
	std::string str("Test string...");
	std::size_t length = str.copy(buffer, 6, 5);//拷贝了6个字符第五个字符之后的string
	buffer[length] = '\0';
	std::cout << buffer << endl;
	std::cout << "buffer contains: " << buffer << '\n';
	return 0;
}

13.std::string::find

函数用于在字符串中查找指定的子串或字符。它有多种重载形式,以适应不同的查找需求。

#include <iostream>       // std::cout
#include <string>         // std::string

int main()
{
    std::string str("There are two needles in this haystack with needles.");
    std::string str2("needle");

    // different member versions of find in the same order as above:
    std::size_t found = str.find(str2);
    if (found != std::string::npos)//static const size_t npos = -1;
        std::cout << "first 'needle' found at: " << found << '\n';

    found = str.find("needles are small", found + 1, 6);
    if (found != std::string::npos)
        std::cout << "second 'needle' found at: " << found << '\n';

    found = str.find("haystack");
    if (found != std::string::npos)
        std::cout << "'haystack' also found at: " << found << '\n';

    found = str.find('.');
    if (found != std::string::npos)
        std::cout << "Period found at: " << found << '\n';

    // let's replace the first needle:
    str.replace(str.find(str2), str2.length(), "preposition");
    std::cout << str << '\n';

    return 0;
}

;