文章目录
1.string 介绍
string类文档介绍
总结:
1.string是表示字符串的字符串类
2.该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
3.string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>string;
4.不能操作多字节或者变长字符的序列。
5.在使用string类时,必须包含#include头文件以及using namespace std(或是单独展开std::string)
string类的实例化标准
类的实例化标准分为string、u16string、u32string 和 wstring 四种,他们都是 C++ 中用于表示字符串的类,但它们的底层字符类型和编码方式不同:
string:
底层字符类型:char
编码方式:使用单字节编码,通常采用 ASCII 或 UTF-8 编码。
示例:std::string myString = “Hello, world!”;
u16string:
底层字符类型:char16_t
编码方式:使用两个字节表示一个字符,通常采用 UTF-16 编码。
示例:std::u16string myString = u"Hello, world!";
u32string:
底层字符类型:char32_t
编码方式:使用四个字节表示一个字符,通常采用 UTF-32 编码。
示例:std::u32string myString = U"Hello, world!";
wstring:
底层字符类型:wchar_t
编码方式:宽字符编码,可以是 UTF-16 或 UTF-32,具体取决于平台。
示例:std::wstring myString = L"Hello, world!";
2.string类的常用接口说明
2.1 总表
函数名称 | 功能说明 |
---|---|
2.2 | |
string(); | 构造空的string类对象,即空字符串 |
string (const string& str); | 拷贝构造函数 |
string (const string& str, size_t pos, size_t len = npos); | 使用另一个 std::string 对象的子串来创建一个新的字符串对象,从给定的位置 pos 复制长度为 len 的子串。 |
string (const char* s); | 用C-string来构造string类对象 |
string (const char* s, size_t n); | 根据部分字符数组来创建一个新的字符串对象 |
string (size_t n, char c); | string类对象中包含n个字符c |
template string (InputIterator first, InputIterator last); | 使用迭代器范围 [first, last) 来创建一个新的字符串对象,范围内的字符将被复制到字符串中。 |
2.3 | |
size | 返回字符串有效字符长度 |
length | 返回字符串有效字符长度 |
max_size | 返回字符串对象能够容纳的最大字符数 |
resize | 用于改变字符串对象的长度 |
capacity | 返回空间总大小 |
reserve | 为字符串预留空间 |
clear | 清空有效字符 |
empty | 检测字符串是否为空串,是返回true,否则返回false |
shrink_to_fit | 要求字符串对象释放多余的内存空间,将容量调整为与字符串长度相同 |
2.4 | |
operator[] | 访问字符串中指定位置 pos 处的字符 |
at | 访问字符串中指定位置 pos 处的字符 |
back | 获取字符串的第一个字符 |
front | 获取字符串的最后一个字符 |
2.5 | |
begin() 和 end() | begin() 函数返回一个指向字符串首字符的迭代器,而 end() 函数返回一个指向字符串末尾后一个字符的迭代器 |
rbegin() 和 rend() | rbegin() 函数返回一个指向字符串最后一个字符的逆向迭代器,而 rend() 函数返回一个指向字符串首字符前一个位置的逆向迭代器 |
cbegin() 和 cend() | cbegin() 函数返回一个指向字符串首字符的 const 迭代器,而 cend() 函数返回一个指向字符串末尾后一个字符的 const 迭代器(末尾后的一个位置)。 |
crbegin() 和 crend() | crbegin() 函数返回一个指向字符串最后一个字符的 const 逆向迭代器,而 crend() 函数返回一个指向字符串首字符前一个位置的 const 逆向迭代器。 |
2.6 | |
operator+= | 用于字符串的连接 |
append | 在字符串末尾添加字符或字符序列 |
push_back | 在字符串末尾添加一个字符 |
assign | 将新的内容赋值给字符串对象,从而修改字符串的内容 |
insert | 在指定位置 pos 处插入字符或字符序列 |
erase | 删除指定位置的字符或字符范围 |
replace | 替换指定位置或字符范围的字符 |
swap | 调用该函数的字符串对象与参数表示的另一个字符串对象的内容进行交换 |
pop_back | 删除字符串中的最后一个字符 |
2.7 | |
c_str() | 返回C格式字符串 |
data() | 返回字符串 |
get_allocator() | 返回与字符串关联的分配器对象的副本 |
copy() | 复制字符到指定位置 |
find() | 查找字符,返回该字符的位置 |
substr() | 复制字符串,从指定位置开始 |
compare() | 比较字符串 |
2.8 | |
operator+ | 将两个字符串连接,返回一个新的字符串 |
== != <( <= > >= | 字符串大小比较 |
swap() | 交换两个字符串 |
>>和<< | 使字符串可以直接输入输出 |
getline() | 获取字符串,直到换行结束 |
to_string() | 将其他类型转化为字符串类型 |
npos | size_t的最大值 |
2.2string类对象的常见构造
函数名称 | 功能说明 |
---|---|
string(); | 构造空的string类对象,即空字符串 |
string (const string& str); | 拷贝构造函数 |
string (const string& str, size_t pos, size_t len = npos); | 使用另一个 std::string 对象的子串来创建一个新的字符串对象,从给定的位置 pos 复制长度为 len 的子串。 |
string (const char* s); | 用C-string来构造string类对象 |
string (const char* s, size_t n); | 根据部分字符数组来创建一个新的字符串对象 |
string (size_t n, char c); | string类对象中包含n个字符c |
template string (InputIterator first, InputIterator last); | 使用迭代器范围 [first, last) 来创建一个新的字符串对象,范围内的字符将被复制到字符串中。 |
示例:
1.默认构造函数
default (1) string();
std::string str; // 创建一个空字符串
2.拷贝构造函数
copy (2) string (const string& str);
std::string str1 = "Hello";
std::string str2 = str1; // 使用复制构造函数创建新的字符串对象
3.子串构造函数
substring (3) string (const string& str, size_t pos, size_t len = npos);
std::string str1 = "Hello, World!";
std::string str2 = str1.substr(0, 5); // 使用子串构造函数创建新的字符串对象,内容为 "Hello"
4.字符串字面值构造函数
from c-string (4) string (const char* s);
std::string str = "Hello, World!"; // 使用字符串字面值初始化字符串
5.部分字符数组构造函数
from sequence (5) string (const char* s, size_t n);
const char* str = "Hello, World!";
std::string new_str(str, 5); // 使用字符数组的前5个字符 "Hello" 来创建新的字符串对象
6.字符重复构造函数
fill (6) string (size_t n, char c);
std::string str(5, 'A'); // 创建一个包含5个字符'A'的字符串 "AAAAA"
7.迭代器范围构造函数
range (7) template <class InputIterator> string (InputIterator first, InputIterator last);
std::string str("Hello, World!");
std::string sub_str(str.begin(), str.begin() + 5); // 使用迭代器范围构造函数创建新的字符串对象,内容为 "Hello"
2.3 string类对象的容量操作
函数名称 | 功能说明 |
---|---|
size | 返回字符串有效字符长度 |
length | 返回字符串有效字符长度 |
max_size | 返回字符串对象能够容纳的最大字符数 |
resize | 用于改变字符串对象的长度 |
capacity | 返回空间总大小 |
reserve | 为字符串预留空间 |
clear | 清空有效字符 |
empty | 检测字符串是否为空串,是返回true,否则返回false |
shrink_to_fit | 要求字符串对象释放多余的内存空间,将容量调整为与字符串长度相同 |
示例: |
1.返回字符串有效字符长度
size_type size() const;
string s1("hello world");
//利用有效长度逐个打印字符,并间隔打印
for (size_t i = 0; i < s1.size(); ++i)
{
cout << s1[i] << ' ';
}
2.返回字符串有效字符长度
size_type length() const;
size() 和 length() 是完全等价的,它们都返回字符串对象中字符的数量,没有区别。
这两个函数的作用是相同的,只是命名不同,为了提供更多的编程灵活性和可读性,可以根据个人偏好选择使用 size() 或 length()。
在实际使用中,你可以根据自己的喜好和项目约定,选择使用 size() 或 length() 来获取字符串的长度,两者效果完全相同。一般情况下,size() 更为常用,因为在 C++ 标准库中,很多容器都提供了 size() 成员函数用于获取容器中元素的数量,包括 std::string、std::vector 等。所以,使用 size() 可以保持代码的一致性和易读性。
3.返回字符串对象能够容纳的最大字符数
size_type max_size() const;
std::string str;
std::cout << "Max size: " << str.max_size() << std::endl;
max_size() 函数返回字符串对象在当前系统环境下能够容纳的最大字符数,这个值取决于平台和编译器,并且通常是一个非常大的值。它的含义是字符串对象的理论上限,表示在当前平台和环境下,该类型的字符串对象最多能够容纳的字符数量。
4.用于改变字符串对象的长度
void resize (size_type n);
void resize (size_type n, charT c);
第一个版本的 resize() 函数用于改变字符串对象的长度。
resize() 会将字符串的长度调整为 n,如果 n 小于当前长度,则会截断字符串;如果 n 大于当前长度,则会在末尾添加空字符以扩展字符串长度。
第二个版本的 resize() 会将字符串的长度调整为 n,同时用字符 c 来填充新添加的字符(仅当 n 大于当前长度时生效)。
示例:
std::string str = "Hello";
str.resize(10); // 调整字符串长度为 10,现在 str 为 "Hello "
str.resize(15, '-'); // 调整字符串长度为 15,用字符 '-' 填充,现在 str 为 "Hello-----"
5.返回空间总大小
size_type capacity() const;
capacity() 函数返回当前字符串对象的容量,即字符串对象在不重新分配内存的情况下所能容纳的最大字符数。它的值可能小于或等于 max_size(),取决于当前字符串对象的实际内存分配情况。在 C++ 中,std::string 类采用动态分配内存的方式存储字符串,当字符串的长度超过当前容量时,字符串会自动重新分配更大的内存空间。
6.为字符串预留空间
void reserve (size_type n = 0);
在 C++ 的 std::string 类中,reserve() 是一个成员函数,用于请求字符串对象重新分配内存,以便能够容纳至少指定数量的字符。这个函数在字符串需要频繁增长长度时非常有用,它可以避免多次内存分配和拷贝操作,从而提高性能。
std::string str = "Hello";
std::cout << "Capacity before reserve: " << str.capacity() << std::endl; // 输出当前容量
str.reserve(20); // 请求重新分配至少能容纳20个字符的内存空间
std::cout << "Capacity after reserve: " << str.capacity() << std::endl; // 输出重新分配后的容量
在上面的示例中,我们先输出了字符串 str 的当前容量,然后调用 reserve() 函数请求重新分配至少能容纳 20 个字符的内存空间,最后再次输出字符串 str 的容量。请注意,重新分配内存后,容量可能超过请求的 n 值,这是为了避免频繁的内存重新分配。
使用 reserve() 函数可以优化字符串对象的内存使用,特别是在预知字符串会变得较长时,提前分配足够的内存空间,减少动态内存分配和拷贝操作,从而提高程序的性能。但要注意,过度分配内存可能导致资源浪费,应根据实际情况合理选择容量。
7.清空有效字符
void clear();
使用 clear() 函数会将字符串对象的内容清空,即将其长度设置为 0,但并不会释放内存或缩小容量。它会将字符串对象变为空字符串,等效于给字符串赋值一个空字符串。
std::string str = "Hello, World!";
std::cout << "Before clear: " << str << std::endl; // 输出原字符串内容
str.clear(); // 清空字符串内容,使其变为空字符串
std::cout << "After clear: " << str << std::endl; // 输出空字符串
在上面的示例中,我们先输出字符串 str 的内容,然后调用 clear() 函数将其内容清空,最后再次输出字符串 str,此时已经变为空字符串。
clear() 函数在清空字符串内容时非常方便,尤其在需要重新使用同一个字符串对象或者需要重置字符串内容的情况下,可以使用这个函数来快速清空字符串。请注意,clear() 只清空字符串内容,不会释放内存或改变容量。如果需要释放内存或缩小容量,可以使用 shrink_to_fit() 函数。
8.检测字符串是否为空串
bool empty() const;
empty() 函数返回一个 bool 类型的值,如果字符串对象为空,则返回 true,否则返回 false。
std::string str1 = "Hello";
std::string str2;
if (str1.empty()) {
std::cout << "str1 is empty." << std::endl;
} else {
std::cout << "str1 is not empty." << std::endl;
}
if (str2.empty()) {
std::cout << "str2 is empty." << std::endl;
} else {
std::cout << "str2 is not empty." << std::endl;
}
在上面的示例中,我们创建了两个 std::string 对象 str1 和 str2,然后使用 empty() 函数检查它们是否为空。str1 包含字符 “Hello”,所以 str1.empty() 返回 false,而 str2 是一个空字符串,所以 str2.empty() 返回 true。
empty() 函数在实际编程中非常有用,可以用于检查字符串是否为空,从而根据情况进行逻辑判断和处理。
9.释放多余的内存空间
void shrink_to_fit();
该函数用于要求字符串对象释放多余的内存空间,将容量调整为与字符串长度相同。这样可以减少不必要的内存使用。
std::string str = "Hello";
str.reserve(20); // 请求重新分配至少能容纳20个字符的内存空间
// 其他操作...
str.shrink_to_fit(); // 释放多余的内存空间,容量调整为与字符串长度相同
使用 reserve() 和 shrink_to_fit() 函数可以有效地控制字符串对象的内存使用,避免不必要的内存分配和释放。请注意,在字符串需要频繁改变长度时,动态地调整容量可能是一个优化的策略。不过,也要根据实际情况进行合理的内存管理,以避免过度分配内存导致的资源浪费。
注意:
1.size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
2.clear()只是将string中有效字符清空,不改变底层空间大小。
3.resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
4.reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserve不会改变容量大小。
2.4string类对象的元素访问
函数名称 | 功能说明 |
---|---|
operator[] | 访问字符串中指定位置 pos 处的字符 |
at | 访问字符串中指定位置 pos 处的字符 |
back | 获取字符串的第一个字符 |
front | 获取字符串的最后一个字符 |
- operator[]:
reference operator[](size_type pos);
const_reference operator[](size_type pos) const;
operator[] 函数用于访问字符串中指定位置 pos 处的字符。返回一个引用,允许您读取或修改该位置上的字符。如果使用 const 修饰符,则表示对字符串进行只读访问。
std::string str = "Hello";
char first_char = str[0]; // 获取字符串的第一个字符 'H'
str[0] = 'h'; // 修改字符串的第一个字符为 'h',现在 str 为 "hello"
2.at():
reference at(size_type pos);
const_reference at(size_type pos) const;
at() 函数与 operator[] 类似,也用于访问字符串中指定位置 pos 处的字符。不同之处在于,at() 函数会检查索引是否有效,如果索引超出字符串范围,则抛出 std::out_of_range 异常。
std::string str = "Hello";
char first_char = str.at(0); // 获取字符串的第一个字符 'H'
str.at(0) = 'h'; // 修改字符串的第一个字符为 'h',现在 str 为 "hello"
3.front():
reference front();
const_reference front() const;
front() 函数用于获取字符串的第一个字符,返回一个引用。如果使用 const 修饰符,则表示对字符串进行只读访问。
std::string str = "Hello";
char first_char = str.front(); // 获取字符串的第一个字符 'H'
4.back():
reference back();
const_reference back() const;
back() 函数用于获取字符串的最后一个字符,返回一个引用。如果使用 const 修饰符,则表示对字符串进行只读访问。
std::string str = "Hello";
char last_char = str.back(); // 获取字符串的最后一个字符 'o'
这些函数提供了多种方式来访问字符串的内容,你可以根据需要选择合适的函数来读取或修改字符串中的字符。请注意,在使用这些函数时要注意索引的有效范围,避免访问越界导致的未定义行为。
2.5 string类对象的Iterators(迭代器)接口
在 C++ 的 std::string 类中,提供了许多 Iterators(迭代器)接口函数,用于遍历和访问字符串中的字符。这些函数允许你以迭代器的方式访问字符串的内容,从而对字符串进行遍历和操作。
函数名称 | 功能说明 |
---|---|
begin() 和 end() | begin() 函数返回一个指向字符串首字符的迭代器,而 end() 函数返回一个指向字符串末尾后一个字符的迭代器 |
rbegin() 和 rend() | rbegin() 函数返回一个指向字符串最后一个字符的逆向迭代器,而 rend() 函数返回一个指向字符串首字符前一个位置的逆向迭代器 |
cbegin() 和 cend() | cbegin() 函数返回一个指向字符串首字符的 const 迭代器,而 cend() 函数返回一个指向字符串末尾后一个字符的 const 迭代器(末尾后的一个位置)。 |
crbegin() 和 crend() | crbegin() 函数返回一个指向字符串最后一个字符的 const 逆向迭代器,而 crend() 函数返回一个指向字符串首字符前一个位置的 const 逆向迭代器。 |
1.begin() 和 end():
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
begin() 函数返回一个指向字符串首字符的迭代器,而 end() 函数返回一个指向字符串末尾后一个字符的迭代器(末尾后的一个位置)。const 修饰符版本的函数用于在 const 对象上获取 const 迭代器。
string s("hello");
string::iterator it = s.begin();
while (it != s.end())
{
cout << *it << " ";
++it;
}
cout << endl;
2.rbegin() 和 rend():
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
rbegin() 函数返回一个指向字符串最后一个字符的逆向迭代器,而 rend() 函数返回一个指向字符串首字符前一个位置的逆向迭代器。const 修饰符版本的函数用于在 const 对象上获取 const 逆向迭代器。
std::string str = "Hello";
for (auto it = str.rbegin(); it != str.rend(); ++it) {
std::cout << *it; // 逆向遍历输出字符串的所有字符 "olleH"
}
3.cbegin() 和 cend():
const_iterator cbegin() const;
const_iterator cend() const;
cbegin() 函数返回一个指向字符串首字符的 const 迭代器,而 cend() 函数返回一个指向字符串末尾后一个字符的 const 迭代器(末尾后的一个位置)。
4.crbegin() 和 crend():
const_reverse_iterator crbegin() const;
const_reverse_iterator crend() const;
crbegin() 函数返回一个指向字符串最后一个字符的 const 逆向迭代器,而 crend() 函数返回一个指向字符串首字符前一个位置的 const 逆向迭代器。
这些 Iterators 接口函数提供了多种方式来遍历字符串的内容,并且支持正向和逆向迭代器。你可以根据需要选择合适的迭代器类型来遍历字符串,其中 begin() 和 end() 是最常用的迭代器接口函数。
范围for和迭代器的关系
范围for循环(Range-based for loop)和迭代器(Iterators)是 C++ 中两种不同的用于遍历容器或可迭代对象的方式。它们在语法和用法上有一些区别,但本质上都是用来迭代访问容器或序列中的元素。
1.范围for循环(Range-based for loop):
范围for循环是 C++11 引入的一种语法糖,用于简化容器或序列的遍历。它的语法形式如下:
for (element_type element : container) {
// 对每个元素执行的操作
}
在这个循环中,container 是一个可迭代对象,可以是标准容器(如 std::vector、std::list、std::map 等)、数组、字符串等等。element 是容器中的每个元素的副本,可以用于访问和操作该元素。范围for循环会自动遍历容器,并在每次迭代时将容器中的元素赋值给 element,直到容器的末尾为止。
示例:
std::string str = "Hello";
for (char c : str) {
std::cout << c << " "; // 输出:H e l l o
}
2.迭代器:
迭代器也可以用于遍历 std::string 中的每个字符,它提供了更灵活的方式来访问字符串的内容,可以自定义遍历方式。std::string 类提供了两种迭代器:iterator 和 const_iterator。
iterator:用于修改 std::string 对象中的字符。
const_iterator:用于只读访问 std::string 对象中的字符。
示例:
std::string str = "Hello";
for (std::string::iterator it = str.begin(); it != str.end(); ++it) {
std::cout << *it << " "; // 输出:H e l l o
}
或者使用 auto 关键字简化迭代器声明:
for (auto it = str.begin(); it != str.end(); ++it) {
std::cout << *it << " "; // 输出:H e l l o
}
需要注意的是,范围for循环和迭代器都可以用来遍历 std::string 中的字符,范围for循环更简洁方便,特别适用于遍历整个字符串;而迭代器提供了更多灵活性,可以用于实现更复杂的遍历和访问方式,比如只遍历部分字符或以逆序遍历字符串。在实际应用中,你可以根据具体需求选择合适的遍历方式。
2.6 string类对象的修改器(Modifiers)
函数名称 | 功能说明 |
---|---|
operator+= | 用于字符串的连接 |
append | 在字符串末尾添加字符或字符序列 |
push_back | 在字符串末尾添加一个字符 |
assign | 将新的内容赋值给字符串对象,从而修改字符串的内容 |
insert | 在指定位置 pos 处插入字符或字符序列 |
erase | 删除指定位置的字符或字符范围 |
replace | 替换指定位置或字符范围的字符 |
swap | 调用该函数的字符串对象与参数表示的另一个字符串对象的内容进行交换 |
pop_back | 删除字符串中的最后一个字符 |
1.operator+=
+= 运算符是字符串的连接操作符,也称为字符串的拼接运算符。使用 += 运算符,您可以将一个字符串连接到另一个字符串的末尾,从而实现字符串的拼接。
+= 运算符的原型如下:
basic_string& operator+=(const basic_string& str);
basic_string& operator+=(const charT* s);
basic_string& operator+=(charT ch);
+= 运算符有三个重载版本,分别用于将另一个字符串、C 风格字符串(以 null 结尾的字符数组)或单个字符连接到当前字符串的末尾。
示例:
std::string str = "Hello";
str += " World"; // 将字符串 " World" 连接到 str 的末尾,现在 str 变为 "Hello World"
str += '!'; // 将字符 '!' 连接到 str 的末尾,现在 str 变为 "Hello World!"
在上述示例中,我们通过使用 += 运算符将字符串 " World" 和字符 ‘!’ 连接到字符串 str 的末尾,实现了字符串的拼接。
需要注意的是,+= 运算符会直接修改调用它的字符串对象,将指定的内容连接到字符串的末尾。如果你希望连接两个字符串而不修改原始字符串,可以使用 + 运算符来创建一个新的字符串,而不会修改原有的字符串对象。例如:
std::string str1 = "Hello";
std::string str2 = " World";
std::string combined = str1 + str2; // 创建一个新的字符串,不修改原有字符串
使用 += 运算符或 + 运算符,取决于你希望修改原有字符串还是创建新的字符串,或者根据具体的需求来选择适合的方法。
2.append
append() 函数用于在字符串的末尾添加字符或字符序列,从而实现字符串的拼接。
append() 函数有多个重载形式,提供了不同的方式来添加内容到字符串的末尾。以下是 std::string 类中 append() 函数的几种重载形式及其介绍和使用方法:
basic_string& append(const charT* s);
这个重载函数将一个 C 风格字符串(以 null 结尾的字符数组)添加到字符串的末尾。
std::string str = "Hello";
str.append(" World"); // 在末尾添加字符串 " World",现在 str 为 "Hello World"
basic_string& append(const charT* s, size_type n);
这个重载函数将一个指定长度的字符数组添加到字符串的末尾。
std::string str = "Hello";
str.append(" World", 5); // 在末尾添加字符数组 " Worl"(前5个字符),现在 str 为 "Hello Worl"
basic_string& append(const basic_string& str);
这个重载函数将另一个 std::string 对象的内容添加到当前字符串的末尾。
std::string str1 = "Hello";
std::string str2 = " World";
str1.append(str2); // 将 str2 的内容添加到 str1 的末尾,现在 str1 为 "Hello World"
basic_string& append(const basic_string& str, size_type pos, size_type n);
这个重载函数将另一个 std::string 对象从指定位置 pos 处开始的 n 个字符添加到当前字符串的末尾。
std::string str1 = "Hello";
std::string str2 = "World";
str1.append(str2, 1, 3); // 将 str2 从位置1(包含)开始的3个字符 "orl" 添加到 str1 的末尾,现在 str1 为 "Helloorl"
basic_string& append(size_type n, charT ch);
这个重载函数将重复 n 次的字符 ch 添加到字符串的末尾。
std::string str = "Hello";
str.append(3, '!'); // 在末尾添加3个字符 '!',现在 str 为 "Hello!!!"
这些 append() 函数提供了多种方式来将内容添加到字符串的末尾,从而实现字符串的拼接。
3.push_back
void push_back(charT ch);
使用 push_back() 函数可以将一个字符 ch 添加到字符串的末尾。
示例:
std::string str = "Hello";
str.push_back('!'); // 在末尾添加字符 '!',现在 str 变为 "Hello!"
在上述示例中,我们通过使用 push_back() 函数在字符串 str 的末尾添加了字符 ‘!’,从而实现了在字符串中添加一个字符的操作。
需要注意的是,push_back() 函数会直接修改调用它的字符串对象,在字符串的末尾添加指定的字符。在使用 push_back() 之前,应该确保字符串的长度仍然在合理的范围内,避免发生字符串的溢出。在实际使用中,务必注意处理字符串长度和内存的限制。另外,C++11 之后的版本还引入了字符串拼接操作符 +=,可以使用 += 运算符来在字符串的末尾添加字符,更加简洁方便。
4.assign
assign() 函数用于将新的内容赋值给字符串对象,从而修改字符串的内容。
assign() 函数有多个重载形式,提供了不同的方式来赋值新的内容给字符串。以下是 std::string 类中 assign() 函数的几种重载形式及其介绍和使用方法:
basic_string& assign(const charT* s);
这个重载函数将一个 C 风格字符串(以 null 结尾的字符数组)赋值给字符串对象。
std::string str;
str.assign("Hello"); // 将 C 风格字符串 "Hello" 赋值给字符串对象 str
basic_string& assign(const charT* s, size_type n);
这个重载函数将一个指定长度的字符数组赋值给字符串对象。
std::string str;
str.assign("Hello", 3); // 将字符数组 "Hel"(前三个字符)赋值给字符串对象 str
basic_string& assign(const basic_string& str);
这个重载函数将另一个 std::string 对象的内容赋值给当前字符串对象。
std::string str1 = "Hello";
std::string str2;
str2.assign(str1); // 将 str1 的内容赋值给 str2
basic_string& assign(const basic_string& str, size_type pos, size_type n);
这个重载函数将另一个 std::string 对象从指定位置 pos 处开始的 n 个字符赋值给当前字符串对象。
std::string str1 = "Hello";
std::string str2;
str2.assign(str1, 1, 3); // 将 str1 从位置1(包含)开始的3个字符 "ell" 赋值给 str2
basic_string& assign(size_type n, charT ch);
这个重载函数将重复 n 次的字符 ch 赋值给字符串对象。
std::string str;
str.assign(5, 'x'); // 将字符 'x' 重复5次赋值给字符串对象 str,结果为 "xxxxx"
这些 assign() 函数提供了多种方式来将新的内容赋值给字符串对象,从而修改字符串的内容。
5.insert
insert() 函数用于在指定位置插入字符或字符序列,从而改变字符串的内容。
insert() 函数有多个重载形式,提供了不同的方式来在字符串中插入字符或字符序列。以下是 std::string 类中 insert() 函数的几种重载形式及其介绍和使用方法:
basic_string& insert(size_type pos, const charT* s);
这个重载函数在字符串中的指定位置 pos 处插入一个 C 风格字符串(以 null 结尾的字符数组)。
std::string str = "Hello";
str.insert(2, "xx"); // 在位置2处插入字符串 "xx",现在 str 变为 "Hexxllo"
basic_string& insert(size_type pos, const charT* s, size_type n);
这个重载函数在字符串中的指定位置 pos 处插入一个指定长度的字符数组。
std::string str = "Hello";
str.insert(3, "xx", 1); // 在位置3处插入字符数组 "x"(前1个字符),现在 str 变为 "Helxlo"
basic_string& insert(size_type pos, const basic_string& str);
这个重载函数在字符串中的指定位置 pos 处插入另一个 std::string 对象的内容。
std::string str1 = "Hello";
std::string str2 = " World";
str1.insert(5, str2); // 在位置5处插入 str2 的内容,现在 str1 变为 "Hello World"
basic_string& insert(size_type pos, const basic_string& str, size_type subpos, size_type sublen);
这个重载函数在字符串中的指定位置 pos 处插入另一个 std::string 对象的子字符串,从 str 的 subpos 处开始,长度为 sublen。
std::string str1 = "Hello";
std::string str2 = "World";
str1.insert(5, str2, 0, 3); // 在位置5处插入 str2 的子字符串 "Wor",现在 str1 变为 "HelloWor"
basic_string& insert(size_type pos, size_type n, charT ch);
这个重载函数在字符串中的指定位置 pos 处插入重复 n 次的字符 ch。
std::string str = "Hello";
str.insert(2, 3, 'x'); // 在位置2处插入3个字符 'x',现在 str 变为 "Hexxxello"
这些 insert() 函数提供了多种方式来在字符串中插入字符或字符序列,从而实现字符串内容的修改。
6.erase
erase() 函数用于从字符串中删除指定位置的字符或字符序列,从而修改字符串的内容。
erase() 函数有多个重载形式,提供了不同的方式来删除字符串中的字符或字符序列。以下是 std::string 类中 erase() 函数的几种重载形式及其介绍和使用方法:
basic_string& erase(size_type pos = 0, size_type n = npos);
这个重载函数删除从指定位置 pos 开始的 n 个字符(默认情况下,删除从 pos 开始的所有字符)。
std::string str = "Hello World";
str.erase(5); // 删除从位置5(包含)开始的所有字符,现在 str 变为 "Hello"
str.erase(0, 3); // 删除从位置0(包含)开始的3个字符,现在 str 变为 "lo"
iterator erase(const_iterator position);
这个重载函数删除指定位置 position 处的字符,并返回一个指向删除后的下一个字符的迭代器。
std::string str = "Hello";
auto it = str.erase(str.begin() + 1); // 删除位置1处的字符 'e',现在 str 变为 "Hllo",it 指向 'l'
iterator erase(const_iterator first, const_iterator last);
这个重载函数删除从 first 到 last-1之间的字符,并返回一个指向删除后的下一个字符的迭代器。
std::string str = "Hello World";
auto first = str.begin() + 6; // 指向字符 'W'
auto last = str.begin() + 11; // 指向字符 '\0'
auto it = str.erase(first, last); // 删除字符 'W' 到 '\0'(不包括\0),现在 str 变为 "Hello ",it 指向 '\0'
这些 erase() 函数提供了多种方式来删除字符串中的字符或字符序列,从而实现字符串内容的修改。
7.replace
replace()函数用于将字符串中的一部分内容替换为新的子串。
replace() 函数有多个重载形式,提供了不同的方式来替换字符串中的一部分内容。以下是 std::string 类中 replace() 函数的几种重载形式及其描述和使用方法:
basic_string& replace(size_type pos, size_type count, const charT* s);
这个重载函数从字符串的位置 pos 开始,用指定的 C 风格字符串(以 null 结尾的字符数组)替换 count 个字符。
std::string str = "Hello, World!";
str.replace(7, 5, "Universe"); // 从位置 7 开始,用 "Universe" 替换 5 个字符,现在 str 变为 "Hello, Universe!"
basic_string& replace(size_type pos, size_type count, const charT* s, size_type n);
这个重载函数从字符串的位置 pos 开始,用指定长度的字符数组中的前 n 个字符替换 count 个字符。
std::string str = "Hello, World!";
str.replace(7, 5, "Earth", 3); // 从位置 7 开始,用 "Ear"("Earth" 的前 3 个字符)替换 5 个字符,现在 str 变为 "Hello, Ear, World!"
basic_string& replace(size_type pos, size_type count, const basic_string& str);
这个重载函数从字符串的位置 pos 开始,用另一个 std::string 对象的内容替换 count 个字符。
std::string str1 = "Hello, World!";
std::string str2 = "Universe";
str1.replace(7, 5, str2); // 从位置 7 开始,用 str2 的内容 "Universe" 替换 5 个字符,现在 str1 变为 "Hello, Universe!"
basic_string& replace(size_type pos, size_type count, const basic_string& str, size_type pos2, size_type count2);
这个重载函数从字符串的位置 pos 开始,用另一个 std::string 对象 str 的从 pos2 处开始的 count2 个字符替换 count 个字符。
std::string str1 = "Hello, World!";
std::string str2 = "Universe";
str1.replace(7, 5, str2, 0, 3); // 从位置 7 开始,用 str2 的子串 "Uni"(从位置 0 开始的 3 个字符)替换 5 个字符,现在 str1 变为 "Hello, Uni, World!"
basic_string& replace(iterator first, iterator last, const charT* s);
这个重载函数用指定的 C 风格字符串(以 null 结尾的字符数组)替换从 first 到 last-1 之间的字符。
std::string str = "Hello, World!";
auto first = str.begin() + 7; // 指向字符 'W'
auto last = str.begin() + 12; // 指向字符 '!'
str.replace(first, last, "Universe"); // 用 "Universe" 替换 'W' 到 '!'(不包括!),现在 str 变为 "Hello, Universe!"
basic_string& replace(iterator first, iterator last, const basic_string& str);
这个重载函数用另一个 std::string 对象 str 的内容替换从 first 到 last-1 之间的字符。
std::string str1 = "Hello, World!";
std::string str2 = "Universe";
auto first = str1.begin() + 7; // 指向字符 'W'
auto last = str1.begin() + 12; // 指向字符 '!'
str1.replace(first, last, str2); // 用 str2 的内容 "Universe" 替换 'W' 到 '!'(不包含 '!'),现在 str1 变为 "Hello, Universe!"
这些 replace() 函数提供了多种方式来替换字符串中的一部分内容,从而实现字符串内容的修改。
8.swap
swap() 函数没有参数,它将调用它的字符串对象与另一个字符串对象进行内容交换。
std::string str1 = "Hello";
std::string str2 = "World";
str1.swap(str2); // 将 str1 和 str2 的内容交换,现在 str1 变为 "World",str2 变为 "Hello"
在上述示例中,通过调用 str1.swap(str2),我们将 str1 和 str2 的内容进行了交换,str1 变为 “World”,而 str2 变为 “Hello”。
这个函数可以在交换两个字符串的内容时非常有用,而不需要对字符逐个交换或使用临时变量来完成交换。由于 swap() 是一个成员函数,所以可以通过调用它来直接对字符串对象进行交换操作,使得代码更简洁和高效。
9.pop_back
pop_back() 函数没有参数,它只需调用它的字符串对象,就会将最后一个字符从字符串中删除。
std::string str = "Hello";
str.pop_back(); // 删除最后一个字符,现在 str 变为 "Hell"
在上述示例中,通过调用 str.pop_back(),我们将字符串 str 的最后一个字符 ‘o’ 删除,从而得到新的字符串 “Hell”。
需要注意的是,使用 pop_back() 之前,应该确保字符串的长度不为零,否则会引发未定义的行为。在调用 pop_back() 之前,通常需要检查字符串是否为空。
2.7 string类对象的操作函数(operations)
函数名称 | 功能说明 |
---|---|
c_str() | 返回C格式字符串 |
data() | 返回字符串 |
get_allocator() | 返回与字符串关联的分配器对象的副本 |
copy() | 复制字符到指定位置 |
find() | 查找字符,返回该字符的位置 |
substr() | 复制字符串,从指定位置开始 |
compare() | 比较字符串 |
1.c_str():
const char* c_str() const;
这个函数返回一个指向以 null 结尾的字符数组(C 字符串)的指针,表示当前字符串的内容。
示例:
std::string str = "Hello";
const char* cstr = str.c_str(); // cstr 指向 "Hello" 的 C 字符串形式
2.data():
const char* data() const;
这个函数返回一个指向字符数组的指针,表示当前字符串的内容。与 c_str() 类似,但 data() 不一定以 null 结尾。
示例:
std::string str = "Hello";
const char* strData = str.data(); // strData 指向 "Hello" 的字符数组形式
3.get_allocator():
allocator_type get_allocator() const noexcept;
这个函数返回当前字符串使用的分配器的副本。
示例:
std::string str = "Hello";
std::allocator<char> alloc = str.get_allocator(); // 获取 str 的分配器副本
4.copy():
size_type copy(charT* dest, size_type count, size_type pos = 0) const;
这个函数从当前字符串中复制 count 个字符到指定位置 pos 开始的字符数组 dest。
示例:
std::string str = "Hello";
char buffer[6];
str.copy(buffer, 5); // 将 str 的前 5 个字符复制到 buffer 中,buffer 现在为 "Hello\0"(带有 null 终止符)
5.find()、rfind()、find_first_of()、find_last_of()、find_first_not_of()、find_last_not_of():
这些函数用于在当前字符串中搜索指定的字符或子字符串,并返回找到的第一个匹配位置或位置偏移。
示例:
std::string str = "Hello, World!";
size_t pos = str.find("World"); // 在 str 中找到子字符串 "World",返回位置 7
size_t lastPos = str.rfind("l"); // 从字符串末尾开始找到字符 'l',返回位置 9
size_t foundPos = str.find_first_of(",!"); // 在 str 中找到第一个出现的 ',' 或 '!',返回位置 5
- substr():
basic_string substr(size_type pos = 0, size_type count = npos) const;
这个函数主要功能是复制子字符串,要求从指定位置开始,并具有指定的长度。如果没有指定长度_Count或_Count+_Off超出了源字符串的长度,则子字符串将延续到源字符串的结尾。
示例:
string s="student12";
string x = s.substr(); //默认时的长度为从开始位置到尾
string y = s.substr(5); //获得字符串s中 从第5位开始到尾的字符串
string z = s.substr(5, 3); //获得字符串s中 从第5位开始的长度为3的字符串
7.compare():
int compare(const basic_string& str) const noexcept;
这个函数用于比较当前字符串与另一个 std::string 对象 str 的大小关系。
示例:
std::string str1 = "Hello";
std::string str2 = "World";
int result = str1.compare(str2); // 返回一个整数,表示 str1 和 str2 的大小关系(类似于字符串比较的结果)
这些成员函数提供了丰富的功能,用于处理字符串的查找、比较、复制、截取等操作
2.8 string类对象的非成员函数和npos
函数名称 | 功能说明 |
---|---|
operator+ | 将两个字符串连接,返回一个新的字符串 |
== != <( <= > >= | 字符串大小比较 |
swap() | 交换两个字符串 |
>>和<< | 使字符串可以直接输入输出 |
getline() | 获取字符串,直到换行结束 |
to_string() | 将其他类型转化为字符串类型 |
npos | size_t的最大值 |
1.operator+(重载运算符+):
template <class CharT, class Traits, class Allocator>
basic_string<CharT, Traits, Allocator> operator+(
const basic_string<CharT, Traits, Allocator>& lhs,
const basic_string<CharT, Traits, Allocator>& rhs);
这个函数模板用于将两个 std::string 对象进行字符串连接,返回一个新的 std::string 对象,包含两个原始字符串的内容。
示例:
std::string str1 = "Hello";
std::string str2 = " World";
std::string result = str1 + str2; // 返回 "Hello World"
2.关系运算符(Relational operators):
== != <( <= > >=
template <class CharT, class Traits, class Allocator>
bool operator==(
const basic_string<CharT, Traits, Allocator>& lhs,
const basic_string<CharT, Traits, Allocator>& rhs);
这些函数模板用于对 std::string 对象进行大小比较。可以通过这些运算符对两个字符串进行逐个字符的比较,从而确定它们的大小关系。
示例:
std::string str1 = "Hello";
std::string str2 = "World";
bool isEqual = (str1 == str2); // 返回 false,因为 str1 不等于 str2
bool isGreater = (str1 > str2); // 返回 true,因为 str1 大于 str2
3.swap():
template <class CharT, class Traits, class Allocator>
void swap(
basic_string<CharT, Traits, Allocator>& lhs,
basic_string<CharT, Traits, Allocator>& rhs);
这个函数模板用于交换两个 std::string 对象的内容,实现两个字符串的快速交换。
示例:
std::string str1 = "Hello";
std::string str2 = "World";
swap(str1, str2); // 将 str1 和 str2 的内容交换,现在 str1 变为 "World",str2 变为 "Hello"
4.operator>> 和 operator<<(重载运算符>>和<<):
template <class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>& operator>>(
std::basic_istream<CharT, Traits>& is, basic_string<CharT, Traits, Allocator>& str);
template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>& operator<<(
std::basic_ostream<CharT, Traits>& os, const basic_string<CharT, Traits, Allocator>& str);
这些函数模板用于在输入输出流中读取或输出字符串内容。operator>> 用于从输入流中提取字符串,而 operator<< 用于将字符串插入到输出流中。
示例:
std::string str;
std::cout << "请输入一个字符串:";
std::cin >> str; // 从标准输入流中读取字符串
std::cout << "您输入的字符串是:" << str << std::endl; // 将字符串输出到标准输出流
5.getline():
template <class CharT, class Traits, class Allocator>
std::basic_istream<CharT, Traits>& getline(
std::basic_istream<CharT, Traits>& is, basic_string<CharT, Traits, Allocator>& str,
CharT delim);
这个函数模板用于从输入流中读取一行内容,并将其存储到字符串 str 中,直到遇到指定的分隔符 delim。
示例:
std::string str;
std::cout << "请输入一行文本:";
std::getline(std::cin, str); // 从标准输入流中读取一行文本并存储到 str 中
std::cout << "您输入的文本是:" << str << std::endl;
这些函数和操作符提供了丰富的功能,可以方便地对字符串进行连接、比较、输入输出等操作。
6.to_string():
string to_string (int val);
string to_string (long val);
string to_string (long long val);
string to_string (unsigned val);
string to_string (unsigned long val);
string to_string (unsigned long long val);
string to_string (float val);
string to_string (double val);
string to_string (long double val);
这个函数将数字常量转换为字符串,返回值为转换完毕的字符串
示例:
string str = std::to_string(56)//整数56变为字符串“56”
npos
npos 是 std::string 类中的一个静态常量成员,用于表示无效或未找到的位置。它是一个特殊的 std::string::size_type 类型的常量,通常被定义为 std::string::npos,其值在不同的编译器和实现中可能不同,但通常被设为 -1 或一个非常大的值,用于表示在字符串中未找到指定的子串或字符。
npos 主要用于字符串查找操作,比如在使用 find()、rfind()、find_first_of()、find_last_of()、find_first_not_of()、find_last_not_of() 等成员函数时,当查找失败或没有找到指定的子串或字符时,这些函数通常会返回 std::string::npos 来表示无效的位置。
示例:
std::string str = "Hello, World!";
std::string::size_type pos1 = str.find("Universe"); // 在 str 中找不到 "Universe",返回 std::string::npos
std::string::size_type pos2 = str.find('X'); // 在 str 中找不到字符 'X',返回 std::string::npos
std::string::size_type pos3 = str.find("World"); // 在 str 中找到 "World",返回 "World" 在 str 中的位置
在上述示例中,当在字符串 str 中找不到 “Universe” 或字符 ‘X’ 时,find() 函数会返回 std::string::npos 表示查找失败。而当找到 “World” 时,find() 函数会返回 “World” 在字符串中的位置。
注意:npos 的值是一个非常大的无符号整数,因此在比较 std::string::size_type 类型的值时,应使用无符号类型的比较方式,避免可能出现的错误。比如使用 pos != std::string::npos 来判断是否找到了指定的子串或字符。