目录
string的定义方式
string的插入
string的拼接
string的删除
string的查找
string的比较
string的替换
string的交换
string的大小和容量
string中元素的访问
string中运算符的使用
string中与迭代器相关的函数
string与字符串之间的转换
string中子字符串的提取
string中的getline函数
string的定义方式
string()
:默认构造函数,创建一个空字符串。
string (const string& str)
:拷贝构造函数,创建一个新的字符串对象,它是给定字符串str
的一个副本。
string (const string& str, size_t pos, size_t len = npos)
:从已存在的字符串str
中提取子串构造新字符串。pos
是开始位置的索引,len
是要提取的字符数;如果省略或设为npos
,则提取从pos
到字符串末尾的所有字符。
string (const char* s)
:从C风格字符串s
构造字符串对象。
string (const char* s, size_t n)
:从C风格字符串s
的前n
个字符构造字符串对象。
string (size_t n, char c)
:创建一个长度为n
,每个字符都为c
的字符串。
template <class InputIterator> string (InputIterator first, InputIterator last)
:这是一个模板构造函数,它接受一对迭代器(first
和last
),在这对迭代器所指定的范围内构造字符串。这使得可以从任何支持迭代访问的对象(如数组、容器等)中构造字符串。
代码演示:
#include <iostream>#include <string>using namespace std;int main() { // 1. 默认构造函数 string strDefault; cout << strDefault << endl; // 2. 拷贝构造函数 string strCopy("Hello"); string strCopied(strCopy); cout << strCopied << endl; // 3. 从已有字符串提取子串构造 string strSubstr("HelloWorld", 6); cout << strSubstr << endl; // 4. 从C风格字符串构造 string strFromCStr("World"); cout << strFromCStr << endl; // 5. 从C风格字符串的部分构造 const char* partCStr = "HelloWorld"; string strPartCStr(partCStr, 5); cout << strPartCStr << endl; // 6. 创建指定长度和字符的字符串 string strCharRepeat(5, 'A'); cout << strCharRepeat << endl; // 7. 使用迭代器构造 char arr[] = { 'H', 'e', 'l', 'l', 'o' }; string strFromIter(arr, arr + sizeof(arr) - 1); cout << strFromIter << endl; return 0;}
代码结果:
string的插入
使用push_back进行尾插
void push_back(char ch);
功能说明:
参数:ch
- 要添加到字符串末尾的字符。返回值:此函数没有返回值,它直接修改调用它的字符串对象,在其末尾增加给定的字符。扩容:如果添加字符导致字符串超出当前容量,std::string
会自动进行内存管理,包括重新分配内存和复制现有内容到新位置,以容纳新增的字符,这个过程对用户透明。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str = "Hello, "; str.push_back('W'); str.push_back('o'); str.push_back('r'); str.push_back('l'); str.push_back('d'); str.push_back('!'); cout << str << endl; // 输出: Hello, World! return 0;}
代码结果:
使用insert插入
插入单个字符:
string& insert(size_type pos, char ch);
参数:pos
- 插入字符的位置(基于0的索引)。ch
- 要插入的字符。返回值:返回对字符串自身的引用,允许链式调用。 插入字符串:
string& insert(size_t pos, const string& str);string& insert(size_t pos, const string& str, size_t subpos, size_t sublen = npos);
第一种形式直接在pos
位置插入整个字符串str
。第二种形式从字符串str
的subpos
位置开始,插入sublen
个字符到pos
位置。如果sublen
被省略或设置为npos
,则插入从subpos
到str
末尾的所有字符。 插入字符数量:
string& insert(size_t pos, size_t count, char ch);
在pos
位置插入count
个字符ch
。 插入迭代器范围:
template <class Iterator>string& insert(size_t pos, Iterator first, Iterator last);
插入由迭代器first
和last
指定的范围内所有字符到pos
位置。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str = "Hello"; // 在索引2的位置插入字符'a' str.insert(2, "a"); cout << str << endl; // 输出: Helalo // 在末尾插入字符串" World" str.insert(str.size(), " World"); cout << str << endl; // 输出: Hela World // 插入重复字符'e'三次 str.insert(1, 3, 'e'); cout << str << endl; // 输出: Heeele World return 0;}
代码结果:
string的拼接
使用append函数完成string的拼接
追加字符串:
string& append(const string& str);
将整个字符串str
追加到当前字符串末尾。 追加子串:
string& append(const string& str, size_t pos, size_t n = npos);
从字符串str
的pos
位置开始追加n
个字符到当前字符串末尾。如果n
等于npos
,则追加从pos
到str
末尾的所有字符。 追加字符数量:
string& append(size_t n, char c);
在字符串末尾追加n
个字符c
。 追加字符数组:
string& append(const char* s);string& append(const char* s, size_t n);
第一种形式追加C风格字符串s
直到遇到空字符\0
。第二种形式追加C风格字符串s
的前n
个字符。 追加迭代器范围:
template <class Iterator>string& append(Iterator first, Iterator last);
追加由迭代器first
和last
指定的范围内所有字符。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str = "Hello"; // 追加字符串" World" str.append(" World"); cout << str << endl; // 输出: Hello World // 追加三个字符'a' str.append(3, '!'); cout << str << endl; // 输出: Hello World!!! // 从"C-style String"中追加前4个字符 const char* cs = "C-style String"; str.append(cs, 4); cout << str << endl; // 输出: Hello World!!!C-st return 0;}
代码结果:
string的删除
使用pop_back进行尾删
void pop_back();
功能说明:
此函数没有返回值,它直接修改调用它的字符串对象,移除其末尾的字符。如果字符串为空,调用pop_back
函数是未定义行为。实践中,一些实现可能会抛出异常或忽略此操作,但最好避免在空字符串上调用此函数。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { std::string str = "Hello, World!"; // 删除末尾的感叹号 str.pop_back(); cout << str << endl; // 输出: Hello, World // 再次删除,这次是'd' str.pop_back(); cout << str << endl; // 输出: Hello, Worl // 继续删除,直至字符串为空 while ( !str.empty() ) { str.pop_back(); } cout << (str.empty() ? "Now the string is empty." : "String still has characters.") << endl; // 输出: Now the string is empty. return 0;}
代码结果:
使用erase删除
删除单个字符:
iterator erase(iterator position);
删除指针position
所指向的字符,并返回下一个字符的迭代器。 删除指定范围内的字符:
iterator erase(iterator first, iterator last);
删除从迭代器first
到last
之间(不包括last
)的所有字符,并返回last
之后的第一个字符的迭代器。 删除指定位置及其后的若干字符:
string& erase(size_t pos = 0, size_t n = npos);
删除从索引pos
开始的n
个字符。如果n
等于npos
,则删除从pos
到字符串末尾的所有字符。返回修改后的字符串的引用。 代码演示:
#include <iostream>#include <string>using namespace std;int main(){ string str = "Hello, World!"; // 删除第7个字符(逗号) str.erase(6, 1); cout << str << endl; // 输出: Hello World! // 删除从位置3到5的字符("lo") str.erase(3, 2); cout << str << endl; // 输出: HelWorld! // 使用迭代器删除"World"之后的所有字符 auto it = str.find("World"); if (it != string::npos) { it += 5; // 移动到"World"之后 str.erase(it, str.end()); } cout << str << endl; // 输出: HelWorld return 0;}
代码结果:
string的查找
使用find函数正向搜索第一个匹配项
查找子串:
size_t find(const string& str, size_t pos = 0) const;
在字符串中查找子串str
首次出现的位置,搜索从索引pos
开始。默认情况下,pos
为0,即从字符串开头开始搜索。 查找单个字符:
size_t find(char c, size_t pos = 0) const;
查找字符c
首次出现的位置,搜索同样从索引pos
开始。 查找子串并指定结束搜索位置:
size_t find(const string& str, size_t pos, size_t n) const;
查找子串str
的前n
个字符首次出现的位置,搜索从索引pos
开始。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str = "Hello, this is a test string."; // 查找子串"test" size_t pos1 = str.find("test"); if (pos1 != string::npos) { cout << "Found 'test' at position: " << pos1 << endl; } else { cout << "'test' not found." << endl; } // 查找字符'a',从位置10开始 size_t pos2 = str.find('a', 0); cout << "Found 'a' after position 0 at: " << pos2 << endl; // 尝试查找不存在的子串 size_t pos3 = str.find("notfound"); if (pos3 == std::string::npos) { cout << "'notfound' not found in the string." << endl; } return 0;}
代码结果:
使用rfind函数反向搜索第一个匹配项
查找子串:
size_t rfind(const string& str, size_t pos = npos) const;
从字符串末尾开始查找子串str
首次出现的位置,可以指定搜索的起始位置pos
为npos
来从字符串的末尾开始搜索,默认也是这样。 查找单个字符:
size_t rfind(char c, size_t pos = npos) const;
从字符串末尾开始查找字符c
首次出现的位置,同样可以指定搜索的起始位置。 查找子串并指定结束搜索位置:
size_t rfind(const string& str, size_t pos, size_t n) const;
从字符串末尾开始查找子串str
的前n
个字符首次出现的位置,搜索从索引pos
开始。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str = "Hello, this is a test. Testing, 1, 2, test."; // 从后往前查找子串"test" size_t pos1 = str.rfind("test"); if (pos1 != string::npos) { cout << "Found 'test' from end at position: " << pos1 << endl; } else { cout << "'test' not found from end." << endl; } // 查找字符't',限制搜索范围 size_t pos2 = str.rfind('t', 20); cout << "Last 't' before position 20 found at: " << pos2 << endl; // 尝试查找不存在的子串 size_t pos3 = str.rfind("notfound"); if (pos3 == std::string::npos) { cout << "'notfound' not found from end in the string." << endl; } return 0;}
代码结果:
string的比较
使用compare函数完成比较
函数原型及返回值意义:
int compare(const string& str) const;int compare(size_t pos1, size_t n1, const string& str) const;int compare(size_t pos1, size_t n1, const string& str, size_t pos2, size_t n2 = npos) const;int compare(const char* s) const;int compare(size_t pos1, size_t n1, const char* s) const;int compare(size_t pos1, size_t n1, const char* s, size_t n2) const;
返回值解释:
如果当前字符串小于比较的字符串,则返回负整数。如果两者相等,则返回0。如果当前字符串大于比较的字符串,则返回正整数。比较整个字符串:
std::string str1 = "apple";std::string str2 = "banana";int result = str1.compare(str2);
如果result < 0
,说明str1
在字典顺序上小于str2
;如果result > 0
,则str1
大于str2
;若result == 0
,两者相等。
比较子串:
std::string str1 = "pineapple";std::string str2 = "apple";int result = str1.compare(4, 5, str2); // 从str1的第4个字符开始,比较5个字符
这里比较的是"apple"与"apple",由于它们相等,返回值将是0。
比较与C风格字符串:
std::string str = "hello";int result = str.compare("world");
比较"hello"与"world"。
指定长度的比较:
std::string str1 = "abcdef";std::string str2 = "abcxyz";int result = str1.compare(0, 3, str2, 0, 3); // 比较前3个字符
比较"abc"与"abc",结果为0,因为两者相同。
string的替换
使用replace函数完成string的替换
替换单个范围的子串:
string& replace(size_t pos, size_t len, const string& str);
从位置pos
开始,替换长度为len
的子字符串为str
。 使用子串替换另一子串:
string& replace(size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);
同样从位置pos
开始,替换长度为len
的子字符串,但是使用str
中的从subpos
开始长度为sublen
的子串进行替换。 用单个字符替换:
string& replace(size_t pos, size_t len, size_t n, char c);
从位置pos
开始,替换长度为len
的子字符串为n
个字符c
。 迭代器范围替换:
string& replace(iterator i1, iterator i2, const string& str);string& replace(iterator i1, iterator i2, size_t n, char c);
使用迭代器i1
和i2
指定的范围内的字符被str
或n
个字符c
替换。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str = "Hello, world! Welcome to the programming world."; // 替换"world"为"universe" size_t pos = str.find("world"); if (pos != string::npos) { str.replace(pos, 5, "universe"); } cout << str << endl; // 输出: Hello, universe! Welcome to the programming world. // 使用子串替换 pos = str.find("programming", pos); if (pos != string::npos) { str.replace(pos, 11, "coding", 4, 4); // 取"coding"的前4个字符 } cout << str << endl; // 输出: Hello, universe! Welcome to the coding world. // 用字符替换 str.replace(0, 7, 5, '-'); cout << str << endl; // 输出: ----- universe! Welcome to the coding world. return 0;}
代码结果:
string的交换
使用swap函数完成两个string类的交换
函数原型:
void swap(string& other);
用法:
这个函数接受一个引用到另一个std::string
对象作为参数,并直接交换两个字符串的内部数据结构,包括它们的字符缓冲区。交换后,两个字符串对象将包含对方之前的字符内容,但它们的容量和其它属性(如分配的内存大小)也会相应交换。
代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str1 = "Hello, World!"; string str2 = "Goodbye, World!"; cout << "Before swapping:\nstr1 = " << str1 << "\nstr2 = " << str2 << endl; // 使用swap函数交换两个字符串的内容 str1.swap(str2); cout << "After swapping:\nstr1 = " << str1 << "\nstr2 = " << str2 << endl; return 0;}
代码结果:
string的大小和容量
使用size函数或length函数获取当前有效字符的个数
size()函数:
原型:size_t size() const;
功能:返回字符串中字符的数量。备注:作为STL容器通用接口的一部分,它符合容器类的一般使用习惯。 length()函数:
原型:size_t length() const;
功能:同样返回字符串中字符的数量。备注:这个函数主要是为了兼容传统的C语言风格的字符串处理,如strlen
函数,使得C++程序员在使用std::string
时能有熟悉的感觉。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { // 初始化一个字符串 string greeting = "Hello, World!"; // 使用size()函数获取字符串长度 cout << "The length of the string using size() is: " << greeting.size() << endl; // 使用length()函数获取字符串长度 cout << "The length of the string using length() is: " << greeting.length() << endl; return 0;}
代码结果:
使用max_size函数获取string对象对多可包含的字符数
函数原型:
size_t max_size() const;
功能解释:
返回值:max_size
函数返回size_type
类型的值,表示当前系统环境下std::string
对象理论上能存储的最大字符数量。size_type
是一个无符号整型,足以存储任何可能的字符串长度。用途:虽然通常情况下不会达到这个极限值,但它可以用来做边界检查,比如在动态分配或调整字符串大小之前,确保操作不会超出可能的容量限制。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str; cout << "The maximum size of a string on this system can be: " << str.max_size() << " characters." << endl; return 0;}
代码结果:
使用capacity函数获取当前对象所分配的存储空间的大小
函数原型:
size_type capacity() const noexcept;
功能说明:
返回值:返回当前字符串对象已分配的存储空间大小,以字符数量为单位。size_type
是一个无符号整型,确保可以表示任何可能的容量值。目的:提供关于字符串内部存储管理的信息,帮助优化字符串操作,比如通过预先调整容量(reserve()
函数)来避免自动增长导致的多次内存重分配。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str("Hello"); cout << "Current string: \"" << str << "\"\n"; cout << "Current capacity: " << str.capacity() << endl; // 添加字符直到触发自动增长 while (str.capacity() == str.size()) { // 这里仅为示例,实际上不会进入循环,因为capacity通常大于size str += 'a'; cout << "Added a character. New capacity: " << str.capacity() << endl; } return 0;}
代码结果:
使用resize改变当前对象的有效字符的个数
函数原型:
void resize(size_type n, char c = '\0');
参数说明:
n
:指定新的字符串长度。如果这个值大于当前长度,则字符串会被扩展,新添加的位置会被字符c
填充;如果这个值小于当前长度,则字符串会被截断到指定长度。c
:可选参数,默认值为\0
(空字符)。当扩展字符串时,如果指定了这个参数,新增的位置将被此字符填充;如果不指定或值为默认,则默认使用空字符填充。 功能描述:
扩展字符串:如果n
大于当前字符串的长度,resize
函数会在字符串末尾添加足够数量的字符c
,直到字符串长度达到n
。缩短字符串:如果n
小于当前字符串的长度,resize
会直接截断字符串,从原字符串末尾移除多出的字符,直到长度为n
。调整容量:resize
操作可能会影响到字符串的容量(即分配给字符串的内存空间),特别是当扩展字符串时,可能需要重新分配内存以容纳更多的字符。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str = "Hello"; // 扩展字符串并在末尾填充'a' str.resize(10, 'a'); cout << "After resizing to 10 with 'a': " << str << endl; // 输出: Helloaaaaaa // 缩短字符串 str.resize(3); cout << "After resizing to 3: " << str << endl; // 输出: Hel return 0;}
代码结果:
使用reserve改变当前对象的容量大小
函数原型:
void reserve(size_type n);
参数说明:
n
:指定要求的最小容量,即至少能存储n
个字符的内存空间。如果n
小于或等于当前的容量,则函数什么也不做。如果n
大于当前的容量,那么string
对象将尝试重新分配内存以满足新的容量需求。 功能描述:
预防内存重分配:通过预先分配足够的内存,当后续通过插入操作增加字符串长度时,只要增加的长度不超过预留的容量,就不会发生内存重分配,从而提高了程序的效率。不改变字符串内容:reserve()
调用不会改变字符串的实际内容或长度,只影响其容量。内存分配策略:实现可能会根据特定的内存管理策略(如分配多于请求的内存以应对未来增长)来决定实际分配的内存大小,但这保证至少能满足n
个字符的存储需求。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str; // 预先分配能容纳100个字符的内存空间 str.reserve(100); cout << "Initial capacity: " << str.capacity() << endl; // 显示初始容量 // 接着可以安全地执行一系列的插入操作,而不会频繁触发内存重分配 for (int i = 0; i < 100; ++i) { str.push_back('A' + (i % 26)); // 填充字母 } cout << "After inserting characters, capacity: " << str.capacity() << endl; // 显示调整后的容量 cout << "Size after insertions: " << str.size() << endl; // 显示实际大小 return 0;}
代码结果:
使用clear删除对象的内容,删除后对象变为空字符串
函数原型:
void clear() noexcept;
功能描述:
清空内容:调用clear()
后,字符串中的所有字符都将被移除,字符串长度变为0。保留容量:虽然字符串变得为空,但它所占用的内存容量(即可以存储的字符数量而无需重新分配内存)通常保持不变。这意味着,再次添加字符时,直到达到原有容量之前,不会触发新的内存分配。性能优势:由于不需要重新分配内存,对于频繁需要清空并重新填充内容的场景,使用clear()
比反复创建新的字符串对象更为高效。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str = "Hello, World!"; cout << "Before clear: \"" << str << "\", Size: " << str.size() << ", Capacity: " << str.capacity() << endl; str.clear(); cout << "After clear: \"" << str << "\", Size: " << str.size() << ", Capacity: " << str.capacity() << endl; return 0;}
代码结果:
使用empty判断对象是否为空
函数原型:
bool empty() const noexcept;
功能描述:
检查字符串状态:empty()
函数不接受任何参数,它检查调用该函数的字符串对象是否为空。返回值:如果字符串长度为0,表示字符串为空,则返回true
;如果字符串包含至少一个字符,则返回false
。常量成员函数:由于它被声明为const
,这意味着它不会修改字符串对象的状态,只读取信息。 代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str1 = ""; string str2 = "Hello"; if (str1.empty()) { cout << "str1 is empty." << endl; } else { cout << "str1 is not empty." << endl; } if (str2.empty()) { cout << "str2 is empty." << endl; } else { cout << "str2 is not empty." << endl; } return 0;}
代码结果:
string中元素的访问
[ ]+下标
代码演示:
#include <iostream>#include <string>using namespace std;int main() { string str = "Hello, World!"; // 访问第一个字符 char firstChar = str[0]; cout << "First character: " << firstChar << endl; // 输出 H // 访问最后一个字符 char lastChar = str[str.size() - 1]; cout << "Last character: " << lastChar << endl; // 输出 !}
代码结果:
使用at访问对象中的元素
代码演示:
#include <iostream>#include <string>#include <stdexcept> // 引入此头文件以处理std::out_of_range异常int main() { try { std::string str = "Hello, World!"; // 安全地访问第一个字符 char firstChar = str.at(0); std::cout << "First character: " << firstChar << std::endl; // 输出 H // 尝试访问超出范围的字符,这将抛出异常 char invalidAccess = str.at(20); // 假设字符串没有这么长 std::cout << "Invalid access character: " << invalidAccess << std::endl; } catch (const std::out_of_range& e) { std::cerr << "Caught an out_of_range exception: " << e.what() << std::endl; } return 0;}
代码结果:
使用范围for访问对象中的元素
代码演示:
#include <iostream>#include <string>int main() { std::string str = "Hello, World!"; // 使用范围for循环遍历字符串中的每个字符 for (char ch : str) { std::cout << ch << std::endl; // 分别打印每个字符 } // 或者,如果你想在一行中打印整个字符串,不换行 std::cout << "Printing the string in one line: "; for (char ch : str) { std::cout << ch; } std::cout << std::endl; // 在所有字符打印完成后换行 return 0;}
代码结果:
使用迭代器访问对象中的元素
代码演示:
#include <iostream>#include <string>int main() { std::string str = "Hello, World!"; // 使用迭代器遍历字符串 for (std::string::iterator it = str.begin(); it != str.end(); ++it) { std::cout << *it << std::endl; // 打印每个字符 } // 使用const_iterator进行只读遍历 for (std::string::const_iterator cit = str.cbegin(); cit != str.cend(); ++cit) { std::cout << *cit; // 同样打印每个字符,但明确表示不修改 } std::cout << std::endl; // 在所有字符打印完成后换行 return 0;}
代码结果:
string中运算符的使用
operator=
代码演示:
#include <iostream>#include <string>using namespace std;int main(){string s1;string s2("CSDN");//支持string类的赋值s1 = s2;cout << s1 << endl; //CSDN//支持字符串的赋值s1 = "hello";cout << s1 << endl; //hello//支持字符的赋值s1 = 'x';cout << s1 << endl; //xreturn 0;}
代码结果:
operator+=
代码演示:
#include <iostream>#include <string>using namespace std;int main(){string s1;string s2("hello");//支持string类的复合赋值s1 += s2;cout << s1 << endl; //hello//支持字符串的复合赋值s1 += " CSDN";cout << s1 << endl; //hello CSDN//支持字符的复合赋值s1 += '!';cout << s1 << endl; //hello CSDN!return 0;}
代码结果:
operator+
基本用法:
字符串与字符串相加字符串与C风格字符串相加字符串与字符相加代码演示:
#include <iostream>#include <string>using namespace std;int main(){string s;string s1("super");string s2("man");char str[] = "woman";char ch = '!';//string类 + string类s = s1 + s2;cout << s << endl; //superman//string类 + 字符串s = s1 + str;cout << s << endl; //superwoman//字符串 + string类s = str + s1;cout << s << endl; //womansuper//string类 + 字符s = s1 + ch;cout << s << endl; //super!//字符 + string类s = ch + s1;cout << s << endl; //!superreturn 0;}
代码结果:
operator>> 和 operator<<
operator<<
(插入运算符):
功能: 该运算符用于将数据插入到输出流中。最常见的用途是在std::cout
上,用于打印变量的值或者字符串到控制台或其他输出设备。
语法::std::cout << expression1 << expression2 ...;
示例:
int age = 25;std::string name = "Alice";std::cout << "Name: " << name << ", Age: " << age << std::endl;
上述代码会输出: Name: Alice, Age: 25
operator>>()
(提取运算符):
功能::该运算符用于从输入流中提取(读取)数据到变量中。最常用的输入流是std::cin
,它通常用于接收用户键盘输入。
语法::std::cin >> variable1 >> variable2 ...;
示例:
int number;std::string inputText;std::cout << "Enter an integer: ";std::cin >> number;std::cout << "Enter some text: ";std::cin >> inputText;
在上述代码中,程序首先提示用户输入一个整数,然后输入一段文本。
relational operators
等于 (==
)
if (str1 == str2) { /* 字符串str1和str2相等 */ }
不等于 (!=
)
if (str1 != str2) { /* 字符串str1和str2不相等 */ }
小于 (<
)
if (str1 < str2) { /* 字符串str1在str2之前 */ }
大于 (>
)
if (str1 > str2) { /* 字符串str1在str2之后 */ }
小于等于 (<=
)
if (str1 <= str2) { /* 字符串str1在str2之前或与之相等 */ }
大于等于 (>=
)
if (str1 >= str2) { /* 字符串str1在str2之后或与之相等 */ }
注意:这些运算符在比较字符串时,按照字符的ASCII(或Unicode)值逐个进行比较,首先是第一个字符,如果相同则继续比较下一个,直到找到不匹配的字符或一个字符串结束。
string中与迭代器相关的函数
与正向迭代器相关的函数
begin函数
函数原型:
iterator begin();const_iterator begin() const;
功能说明:
非const版本:begin()
返回一个迭代器,指向字符串的第一个字符。这个迭代器是可修改的,意味着你可以通过它来修改字符串的内容。
const版本:在const
上下文中(比如字符串为const std::string
类型或者被const
引用或指针引用),begin()
返回一个const_iterator
,它只能用于读取字符串内容,不能修改。
代码演示:
#include <iostream>#include <string>int main() { std::string str = "Hello, World!"; // 遍历字符串 for (auto it = str.begin(); it != str.end(); ++it) { std::cout << *it; // 输出字符串中的每个字符 } std::cout << std::endl; // 在const上下文中的使用 const std::string constStr = "Example"; for (auto cit = constStr.begin(); cit != constStr.end(); ++cit) { std::cout << *cit; // 输出: Example } std::cout << std::endl; return 0;}
代码结果:
end函数
函数原型:
iterator end(); const_iterator end() const;
功能说明:
非const版本:返回一个迭代器,指向字符串的末端,可以用来检测遍历是否结束,但不应解引用此迭代器访问实际的字符。
const版本:在const
上下文中,end()
返回一个const_iterator
,同样指向字符串末端,用于只读操作。
代码演示:
#include <iostream>#include <string>int main() { std::string str = "Hello, World!"; // 遍历字符串 for (auto it = str.begin(); it != str.end(); ++it) { std::cout << *it; // 输出字符串中的每个字符 } std::cout << std::endl; // 在const上下文中的使用 const std::string constStr = "Example"; for (auto cit = constStr.begin(); cit != constStr.end(); ++cit) { std::cout << *cit; // 输出: Example } std::cout << std::endl; return 0;}
代码结果:
与反向迭代器相关的函数
rbegin函数
函数原型:
reverse_iterator rbegin(); const_reverse_iterator rbegin() const;
功能说明:
非const版本:返回一个反向迭代器,初始时指向字符串的最后一个字符。这个迭代器允许你从字符串的末尾向前遍历。
const版本:在const
上下文中,rbegin()
返回一个const_reverse_iterator
,同样指向字符串的最后一个字符,但不允许修改字符串内容。
代码演示:
#include <iostream>#include <string>int main() { std::string str = "Hello, World!"; // 反向遍历字符串 for (auto rit = str.rbegin(); rit != str.rend(); ++rit) { std::cout << *rit; // 逆序输出字符串中的每个字符 } std::cout << std::endl; // 在const上下文中的使用 const std::string constStr = "Example"; for (auto crit = constStr.rbegin(); crit != constStr.rend(); ++crit) { std::cout << *crit; // 逆序输出: !dlroW ,olleH } std::cout << std::endl; return 0;}
代码结果:
rend函数
函数原型:
reverse_iterator rend(); const_reverse_iterator rend() const;
功能说明:
非const版本:返回一个反向迭代器,逻辑上位于字符串的开始位置之前,用于标识反向遍历的终点。
const版本:在const
上下文中,rend()
返回一个const_reverse_iterator
,同样位于开始位置之前,确保遍历时不可修改字符串。
代码演示:
#include <iostream>#include <string>int main() { std::string str = "Hello, World!"; // 反向遍历字符串 for(auto rit = str.rbegin(); rit != str.rend(); ++rit) { std::cout << *rit; // 逆序输出字符串中的每个字符,直到遇到rend() } std::cout << std::endl; // 在const上下文中的使用 const std::string constStr = "Example"; for(auto crit = constStr.rbegin(); crit != constStr.rend(); ++crit) { std::cout << *crit; // 类似地,逆序输出: !elpmaxE } std::cout << std::endl; return 0;}
代码结果:
string与字符串之间的转换
将字符串转换为string
#include <iostream>#include <string>using namespace std;int main(){//方式一string s1("hello world");//方式二char str[] = "hello world";string s2(str);cout << s1 << endl; //hello worldcout << s2 << endl; //hello worldreturn 0;}
使用c_str或data将string转换为字符串
c_str():
功能:c_str()
方法返回一个指向常量字符数组的指针,这个字符数组包含了std::string
对象的内容,末尾带有空字符\0
。这意味着返回的指针指向的数据是不可修改的。适用场景:当你需要将std::string
传递给要求C字符串的API或者C库函数时(例如printf
),应使用c_str()
。因为这些函数期望字符串以\0
结尾,并且通常假设字符串是不可变的。 data():
功能:data()
方法同样返回一个指向字符数组的指针,该数组包含了字符串的内容,但直到C++11标准,data()
返回的指针是否以\0
结尾并未明确规定。从C++11开始,data()
保证了当字符串不是空字符串时,返回的指针指向的数组末尾也会有\0
。不过,与c_str()
不同的是,如果std::string
对象是可变的,通过data()
获得的指针指向的数据可能是可修改的。适用场景:当你只需要读取字符串内容而不需要确保字符串不可变,或者需要传递给接受const char*
但不修改其内容的函数时,可以使用data()
。但在将字符串传递给可能修改其内容的C函数之前,应当谨慎,最好使用c_str()
或确保std::string
对象本身不可变。 代码演示:
#include <iostream>#include <string>int main() { std::string str = "Hello, World!"; // 使用c_str()方法 const char* cStr = str.c_str(); std::cout << "Using c_str(): " << cStr << std::endl; // 使用data()方法 const char* pData = str.data(); std::cout << "Using data(): " << pData << std::endl; return 0;}
代码结果:
string中子字符串的提取
使用substr函数提取string中的子字符串
函数原型:
std::string substr(size_type pos = 0, size_type n = npos) const;
参数说明:
pos:子字符串开始提取的位置索引,默认为0,即字符串的起始位置。n:要提取的字符数量。如果省略或设置为npos
(std::string::npos
表示最大可能值,通常用作结束标志),则提取从pos
开始到字符串结束的所有字符。 返回值:
返回一个新的std::string
对象,包含从原字符串中提取的子字符串。
代码演示:
#include <iostream>#include <string>int main() { std::string originalString = "Hello, World!"; // 提取从位置3开始的5个字符 std::string subStr1 = originalString.substr(3, 5); std::cout << "Substring 1: " << subStr1 << std::endl; // 输出: lo, W // 提取从位置7到字符串结束的子字符串 std::string subStr2 = originalString.substr(7); std::cout << "Substring 2: " << subStr2 << std::endl; // 输出: World! // 提取整个字符串(等效于pos=0, n=npos) std::string subStr3 = originalString.substr(); std::cout << "Substring 3: " << subStr3 << std::endl; // 输出: Hello, World! return 0;}
代码结果:
使用copy函数将string的子字符串复制到字符数组中
代码演示:
#include <iostream>#include <string>#include <algorithm> // 包含std::copy#include <iterator> // 包含std::begin, std::endint main() { std::string str = "Hello, World!"; char charArray[10]; // 目标字符数组 // 使用substr获取子字符串 std::string subStr = str.substr(0, 5); // 获取前5个字符 "Hello" // 使用std::copy将子字符串复制到字符数组 std::copy(subStr.begin(), subStr.end(), charArray); // 确保字符串末尾加上空字符 charArray[subStr.size()] = '\0'; std::cout << "Copied substring: " << charArray << std::endl; return 0;}
代码结果:
string中的getline函数
函数原型:
std::istream& getline(std::istream& is, std::string& str, char delim = '\n');
参数说明:
is:输入流对象,通常为std::cin
,但也可以是其他输入流对象,如文件流std::ifstream
。str:std::string
对象的引用,用于存储读取到的行内容。delim:可选参数,指定的分隔符,默认为\n
(换行符)。读取会停止于该分隔符,但分隔符本身不会被存储在字符串中。 代码演示:
#include <iostream>#include <string>int main() { std::string userInput; std::cout << "请输入一行文本: "; // 读取整行文本直到遇到换行符 std::getline(std::cin, userInput); std::cout << "你输入的是: " << userInput << std::endl; // 另一个例子,使用自定义分隔符 std::cout << "使用自定义分隔符读取(以#结束): "; std::getline(std::cin, userInput, '#'); std::cout << "你输入的是: " << userInput << std::endl; return 0;}
代码演示: