大家好,这里是彩妙呀~

本篇博客会带着大家来学习STL中的string类。
严格来说string不算是STL里,而是c++库中的函数,但按照功能分配上,彩妙吧string归类为STL中。
string类是处理字符序列的核心容器,提供动态内存管理和丰富的成员函数。其设计支持高效字符串操作,避免了传统C风格字符串的常见陷阱。
目录
与c语言类似,string可以使用[]来访问数组中的元素:operator[]重载
反向迭代器(迭代器另一种类模版):reverse_iterator
[使用const来修饰迭代器 const_iterator](#使用const来修饰迭代器 const_iterator)
[范围for (c++11中出现)](#范围for (c++11中出现))
[求string中所存储的数量/字符字数string::size() - string::lenth()](#求string中所存储的数量/字符字数string::size() - string::lenth())
改变string字符串中字符数大小:string::resize()
判断string字符串是否为空:string::empty()
清空string字符串中所有内容:string::clear
[string::operator +=(最常用)](#string::operator +=(最常用))
C++11新增:string::pop_back:删除最后一个字符
[1. string::c_str:获取C风格字符串(const char*),兼容C语言接口](#1. string::c_str:获取C风格字符串(const char*),兼容C语言接口)
string::data:获取字符串数据指针(C++11后与c_str几乎无区别,早期无末尾'\0')
经典函数string::find:从左到右查找子串/字符,返回首次出现的索引(没找到返回string::npos)
为什么要学习string类?
对比:c语言中的字符串
在C语言中,字符串实际上是以空字符( ' \0 ' )结尾的字符数组。这种表示方式带来了许多不便:
cpp
#include <stdio.h>
#include <string.h>
int main() {
char str1[20] = "Hello";
char str2[20] = "World";
char result[40];
// 字符串连接
strcpy(result, str1);
strcat(result, " ");
strcat(result, str2);
printf("%s\n", result); // 输出: Hello World
// 需要手动管理内存
char *dynamic_str = (char*)malloc(100 * sizeof(char));
if(dynamic_str != NULL) {
strcpy(dynamic_str, "Dynamic string");
printf("%s\n", dynamic_str);
free(dynamic_str); // 必须手动释放内存
}
return 0;
}
C语言字符串的主要问题:
手动内存管理:需要预先分配足够的空间
容易出错:容易发生缓冲区溢出
功能有限:需要依赖标准库函数
不够直观:需要记住很多函数名和参数顺序
小部分说明
- 在c++类中,存在很多的函数冗余:例如string类的插入方式有多种,但是实际运用时有些函数重载却不常用,那是因为C++在迭代更新时,要兼容老版本的函数,所以除非万不得已,这些老一点的函数基本上不会舍弃(可以参考python2 -> python3所发生的事情:为什么 Python 3.0 设计成不与 Python 2.X 兼容?主要有哪些地方需要突破才导致这一决定?为什么 Python 3.0 设计成不与 Python 2.X 兼容?)所以,本博客再讲接口时,有些不常用的接口就不在介绍,感兴趣的小伙伴可以通过彩妙提供的链接自己学一下~
标准库中的string类
我们可以通过C/C++标准库网页链接来查询string的声明:string类是C++标准库中的一个类模板实例化,定义在<string>头文件中。它封装了字符序列,并提供了丰富的成员函数来操作字符串。

string的接口统计下来有100+,但是常用的大概在20+左右,所以彩妙也会介绍常用的string类的接口。如果碰到不常用的,也可以通过https://cplusplus.com/reference/网站来查阅学习。
string类的构造函数
在参考文档中,我们发现string有7中构造函数(本篇博客讨论C++98知识,C++11可能会有拓展,不太适合新手学习):

cpp
#include <iostream>
#include <string>
#include <vector>
int main() {
// 1. 默认构造函数
std::string str1;
// 2. 拷贝构造函数
std::string str2("Hello");
std::string str3(str2);
// 3. 子字符串构造函数
std::string str4(str2, 1, 3); // 从位置1开始,取3个字符:"ell"
std::string str5(str2, 2); // 从位置2开始到结尾:"llo"
// 4. C风格字符串构造函数
std::string str6("C++ String"); //等同于std::string str6 = "C++ String"
// 5. 字符序列构造函数
std::string str7("C++ Programming", 3); // 取前3个字符:"C++"
// 6. 填充构造函数
std::string str8(5, 'A'); // "AAAAA"
std::string str9(10, '-'); // "----------"
// 7. 范围构造函数(使用迭代器)
std::vector<char> vec = {'H', 'e', 'l', 'l', 'o'};
std::string str10(vec.begin(), vec.end()); // "Hello"
std::string temp = "World";
std::string str11(temp.begin() + 1, temp.end() - 1); // "orl"
return 0;
}
在这里,比较重要(常用)的构造函数有以下几种 --- 参考文献 ---:
-
string()
构造空的string类对象(空字符串)
-
string(const char s) *
使用C风格字符串构造string类对象
-
string(size_t n, char c)
构造包含n个字符c的string类对象
-
string(const string& s)
拷贝构造函数
cpp
#include <iostream>
#include <string>
int main() {
// 1. string() - 构造空的string类对象(空字符串)
std::string str1;
// 2. string(const char* s) - 使用C风格字符串构造string类对象
std::string str2("Hello World");
const char* cstr = "C++ String";
std::string str3(cstr);
// 3. string(size_t n, char c) - 构造包含n个字符c的string类对象
std::string str4(5, 'A'); // "AAAAA"
std::string str5(10, '*'); // "**********"
// 4. string(const string& s) - 拷贝构造函数
std::string str6(str2); // 拷贝str2的内容
std::string str7 = str3; // 这也调用拷贝构造函数
// 5. 额外演示:混合使用
std::string str8(str2, 6, 5); // 从位置6开始取5个字符:"World"
// 输出所有字符串
std::cout << "str1 (空字符串): \"" << str1 << "\"" << std::endl;
std::cout << "str2 (C风格字符串1): \"" << str2 << "\"" << std::endl;
std::cout << "str3 (C风格字符串2): \"" << str3 << "\"" << std::endl;
std::cout << "str4 (5个'A'): \"" << str4 << "\"" << std::endl;
std::cout << "str5 (10个'*'): \"" << str5 << "\"" << std::endl;
std::cout << "str6 (拷贝str2): \"" << str6 << "\"" << std::endl;
std::cout << "str7 (拷贝str3): \"" << str7 << "\"" << std::endl;
std::cout << "str8 (子字符串): \"" << str8 << "\"" << std::endl;
return 0;
}

string底层成员因该是这样的:
cpp
protected:
char* _str;
size_t _size;
size_t _capacity;
说完了初始化(实例化),下面就要来了解怎么遍历string数组:
string的遍历
string有多种遍历的方式:
与c语言类似,string可以使用[]来访问数组中的元素:operator[]重载
按照,这个重载有两种形态:
cpp
char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;
目的是返回给定位置处的字符的引用。这样就可以通过c语言中,使用变量来逐个遍历string字符串中的元素啦:
cpp
// string::operator[]
#include <iostream>
#include <string>
int main ()
{
std::string str ("Test string");
for (int i=0; i<str.length(); ++i)
{
std::cout << str[i];
}
return 0;
}
他的底层逻辑大概是这样的(自写,如有错误可以指正):
cpp
char& operator[](size_t i) {
assert(i<_size);
return _str[i];
}
使用迭代器来遍历容器中的元素
什么是迭代器?
迭代器(Iterator) 是C++中用于遍历容器(如vector、list、string等)中元素的对象。它类似于指针,提供了访问容器元素的统一接口。
我们可以把迭代器类比成指针:迭代器所处位置就是指针指向位置。但是迭代器不完全(不一定是)是指针(包括智能指针),所以在使用的时候我们要自己做判断。迭代器_参考文献
cpp
std::string::iterator 迭代器名称 = 对应接口函数(例如.begin)
std::string::iterator it_be=str.begin()
std::string::iterator it_en=str.end()
//如果要使用迭代器来表述string字符串,和平常数组类似:使用 * 解引用即可
int main() {
string str("123231123123123qweqweqweqwe3asdadadsad");
// 使用迭代器来遍历字符串
//定义一个string类型的迭代器 it 并指向开头
string::iterator it = str.begin();
for (; it != str.end(); ++it) {
//使用解引用 * 来获取string的内容
cout << *it << endl;
}
return 0;
}
下图是string类中所使用的迭代器:

这里我们要认识string的两个接口:begin与end
string::begin

返回的是指向字符串第一个字符的迭代器。
string::end

返回一个指向字符串末尾字符的迭代器。
内部实现细节我们在后续博客中,会给大家呈现。(但是在日常中,我们只用关心这些都行是干什么用的就行,不必深究)
了解完这两个基础的接口,我们就可以实现一个基础的迭代器的应用:正向迭代器
使用正向迭代器实现string类的遍历
顾名思义:使用迭代器从开头遍历到结尾,就是正向迭代器:
cpp
for (string::iterator it = str.begin(); it != str.end(); ++it) {
//使用解引用 * 来获取string的内容
cout << *it << endl;
}

而反向迭代器与之同理:有两个接口来提供给你迭代器所使用的地址:
string::rbegin

相当于给begin加了个reverse(反转),使得迭代器所指向的内容为string字符串的最后一个字符的下一个字符 ' \0 '。
string::rend

相当于给end加了个reverse(反转),使得迭代器所指向的内容为string字符串的第一个字符。
而这两个接口一起实现了反向迭代器:
反向迭代器(迭代器另一种类模版):reverse_iterator
想要调用者两个接口,不能正常的去使用iterator,而是要在其前面加上reverse_来说明这个迭代器是一个
使用反向迭代器实现string类的遍历
顾名思义:使用迭代器从结尾遍历到开头,可以实现字符串的倒置:
cpp
string str("123231123123123qweqweqweqwe3asdadadsad");
// 使用迭代器来遍历字符串
//定义一个string类型的迭代器 it 并指向开头
for (string::reverse_iterator it = str.rbegin(); it != str.rend(); ++it) {
//使用解引用 * 来获取string的内容
cout << *it << endl;
}
使用const来修饰迭代器 const_iterator
如果我们的string被const修饰,那么无论正向与反向遍历,都要加上const_前缀来修饰迭代器:
cpp
const string st1 = "text string";
for (string::const_iterator it = st1.begin(); it != st1.end(); ++it) {
cout << *it << endl;
}
反向要在reverse_iterator钱再加一个const_修饰。
使用string类内部接口at()
string::at()

这个函数的本质与operator [] 作用差不多,区别是at()函数中有存在函数越界的判断。
范围for (c++11中出现)
范围for 是C++11中提出来的,与迭代器相似(底层就是使用迭代器实现的),可以自动获取每一个值。
cpp
string st2 = "text string";
for (auto it : st2) {
cout << it << endl;
}
//如果确认值类型,可以直接换为其对应类型
string st2 = "text string";
for (char it : st2) {
cout << it << endl;
}
在这里,it的类型为auto,其意思为自动推导:编译器通过后面 : 类型 来自动推导这里要使用迭代器的类型(迭代器在STL容器中通用,例如后面的list,vector等等)),从而实现字符赋值,自动迭代,自动判断结束。
注意::
- 迭代器与范围for从性能来说没有区别,区别只在于写起来方便罢了。
- 在使用范围for尝试修改值时,修改的值不会改变原对象的值(迭代器却可以修改,原理是因为迭代器类似于指正,而范围for相当于调用迭代器,把值拷贝到自身)。
- 如果需要使用范围for修改值,只需要在auto后加一个引用&:auto& it 即可。
适用地方:简化代码---string::iterator it=auto it(编译器会自动推导其类型,写代码就不需要码太多字了(在map章节体现的非常明显))
string类中的Capacity:容量模版
在string类中,有多个模版来求string字符串中的大小,容量的相关内容string类文档说明:

求string中所存储的数量/字符字数string::size() - string::lenth()
对于效果而言,两个函数没有什么区别,都是返回string字符串的长度:


为什么效果一样,但是名称不一样呢?
在C++发展中,string的出现时间要早于STL,而STL容器中所有求大小/长度之类的接口,统一使用string::size(),string为了适配STL容器,也就有了string::size()接口。
所以,为了方便日常编程,求数量之类的都使用::size()接口。
cpp
string st2 = "text string";
cout << st2.size() << endl;
改变string字符串中字符数大小:string::resize()
string::resize参考文档,这个接口我们可以直接去修改string字符串现有字节的数量:
- 当改变的大小 n 小于 字符串所保存数量的大小时:直接取前n个字符作为保留,后面所有的字符做舍弃;
- 如果改变大小 n 大于等于 字符串保存数量大小,并小于string字符串容量大小:这个操作相当于尾部插入元素,即图片中函数重载的第二个函数。当没有传char c时,自动按 ' '尾插。
- 如果改变大小 n 大于string字符串容量大小:直接执行扩容,并走2步骤
上面的论证大家可以自己写代码尝试,彩妙就不细讲了。
求string类的容量:string::capacity

string::capacity文档说明,这个接口返回出string字符串的容量。那么怎么知道string类怎么扩容呢?
cpp
void text() {
string s;
size_t ts = s.capacity();
for (int i = 0; i < 1e3; i++) {
s.push_back('a');
if (ts!=s.capacity()) {
cout << "chang string capasity" << ts << endl;
ts = s.capacity();
}
}
}
我们运行代码:
chang string capasity15
chang string capasity30
chang string capasity60
chang string capasity120
chang string capasity240
chang string capasity480
chang string capasity960
发现,在string类中,扩容逻辑:在申请内存不够用时,变申请本次容量大小的两倍,在进行深拷贝,从而完成扩容。
注意:不同平台编译器的扩容策略不一样:
**VS下是开始使用1.5倍扩容;**而g++是2倍扩容
要着重注意!
string字符串的扩容:string::reserve

string::reverse扩容文档,这个接口是为了减少频繁的扩容,因而降低运行效率,所开发的一个接口:我们可以自己手动扩容。
例如:我们做算法题,有些题目要求字符串的范围(例如1e8之类的)我们就可以直接手动扩容这么大的空间,进而增加运行效率。
cpp
void _string_capasity() {
string s;
s.reserve(1000);
cout << s.capacity() << endl;
s.reserve(2000);
cout << s.capacity() << endl;
//在给string扩容时,只能向大扩容。这个接口本质是修改------capasity数值,而非直接增长
//所以在传入比_capacity小的值,将不做处理
//但是,上面的结论在不同的编译器有不同的处理方法:
//有的编译器是把大小缩减至于size一样的大小才回停止下降。
s.reserve(10);
cout << s.capacity() << endl;
}
/*
结果:
1000
2000
2000
*/
判断string字符串是否为空:string::empty()

string::empty()参考文档,判断当前的字符串是否为空串,如果是返回值为true(非0),反之,则是0。
cpp
#include <iostream>
#include <string>
std::string readLinesUntilEmptyWhile() {
std::string content;
std::string inputLine;
std::cout << "开始输入(输入空行结束):\n";
while (true) {
std::getline(std::cin, inputLine);
if (inputLine.empty()) {
break; // 遇到空行退出循环
}
content += inputLine + '\n';
}
return content;
}
清空string字符串中所有内容:string::clear

string::clear参考文档,直接消除字符串所有的元素,使得字符串变为一个空串:
cpp
void echoLinesUntilDot() {
char c;
std::string buffer;
std::cout << "请输入多行文本,以点号(.)结束输入:\n";
do {
// 读取一个字符
c = std::cin.get();
// 将字符添加到缓冲区
buffer += c;
// 如果遇到换行符
if (c == '\n') {
// 输出当前行
std::cout << buffer;
// 清空缓冲区准备下一行
buffer.clear();
}
} while (c != '.'); // 遇到点号时停止
// 注意:点号本身会被添加到缓冲区,但不会输出(因为输出只在换行时发生)
}
string字符串中插入/删除元素(字符)的接口
要在string字符串后插入元素(尾插)有多个接口:
string::push_back

string::push_back参考文档,使用这个接口可以直接在string字符串后尾插一个字符。注意:只能尾插一个字符,所以这个接口在日常编码时不常用。
cpp
// push_back:追加单个字符
string str3 = "Hi";
str3.push_back('!'); // 只能追加单个char类型字符
cout << "3. push_back 结果: " << str3 << endl; // 输出: Hi!
string::append


string::append参考文档,由于这个接口的函数重载过多,就不全部展示。
这个接口主要的目的就在于:可以更加灵活的追加string字符串(可以指定长度,追加子串等。)
cpp
// append:更灵活的追加(可指定长度、追加子串等)
string str2 = "I love";
str2.append(" C++"); // 追加完整字符串
cout << " append 结果1: " << str2 << endl; // 输出: I love C++
str2.append(" Programming", 0, 4); // 追加子串(从索引0开始,取4个字符)
cout << " append 结果2: " << str2 << endl; // 输出: I love C++ Prog
这个接口在特定场景下使用的比较多。
string::operator +=(最常用)


string::operator+=参考文档,这个运算符重载的接口可以让我们直接在string字符串结尾处追加内容。因为他写起来比较方便,所以是最常用的一个接口:
cpp
// operator+=:向字符串末尾追加内容(最常用)
string str1 = "Hello";
str1 += " World"; // 追加字符串
cout << "operator+= 结果: " << str1 << endl; // 输出: Hello World
插入接口:string::insert


string::insert参考文档,这个函数也有多个函数重载,目的是为了在字符串任意位置插入元素。
这个接口在头插与中间插入时可能会有效率损耗,所以要慎重使用:
cpp
// insert:在指定位置插入内容
string str5 = "HelloWorld";
str5.insert(5, " "); // 在索引5的位置插入空格
cout << "insert 结果: " << str5 << endl; // 输出: Hello World
string::erase:删除指定位置/长度的字符


string::erase参考文档,这个接口可以删除指定位置与长度的字符,但是他与插入一样,在头删与中间删除有损效率,所以也是要慎重使用。
如果要消除pos 后全部的字符,可以不传npos 值,默认就是全部删除。
cpp
// erase:删除指定位置/长度的字符
string str6 = "Hello World";
str6.erase(5); // 从索引5开始删除后面所有字符
cout << "erase 结果1: " << str6 << endl; // 输出: Hello
str6 = "Hello World"; // 重置字符串
str6.erase(5, 1); // 从索引5开始,删除1个字符(删除空格)
cout << "erase 结果2: " << str6 << endl; // 输出: HelloWorld
string::replace:替换指定位置/长度的字符


string::replace参考文档,可以做string字符串的替换,底层实现比较复杂(后续将string类的底层实现会将),效率相对之下也不高,但在一些特定地方(例如查找替换,增删改查之类的应用算法题)与string::find()会有奇用:
cpp
// replace:替换指定位置/长度的字符
string str7 = "I love Java";
str7.replace(7, 4, "C++"); // 从索引7开始,替换4个字符为"C++"
cout << "replace 结果: " << str7 << endl; // 输出: I love C++
//与find搭配用法
string str-s = "hello world hello linux!";
size_t pos = str-s.find(' ');
while (pos != string::npos){
str-s.replase(pos,1,"__");
pos = str-s.find(' ');
}
string::swap:交换两个字符串的内容

string::swap参考文档,这个接口实现了两个string字符串的交换,简单高效:
cpp
// swap:交换两个字符串的内容
string str8_1 = "Apple";
string str8_2 = "Banana";
str8_1.swap(str8_2);
cout << "swap 结果: str8_1=" << str8_1 << ", str8_2=" << str8_2 << endl;
// 输出: str8_1=Banana, str8_2=Apple
C++11新增:string::pop_back:删除最后一个字符

string::pop_back参考文档,这个接口提供尾删新方法:
cpp
// pop_back:删除最后一个字符(C++11及以上支持)
string str9 = "Hello!";
str9.pop_back(); // 删除末尾的'!'
cout << "9. pop_back 结果: " << str9 << endl; // 输出: Hello
string类中其他的相关操作
1. string::c_str:获取C风格字符串(const char*),兼容C语言接口

string::c_str参考文档,这个结构返回指向字符串对象值的 C 字符串所表示形式的指针,主要目的是为了兼容c语言:
cpp
string str = "Hello World! 123 Hello";
// 1. c_str:获取C风格字符串(const char*),兼容C语言接口
const char* c_style_str = str.c_str();
cout << "1. c_str 结果: " << c_style_str << endl;
// 用途示例:传给需要const char*的函数(如C语言的printf)
printf(" c_str 用途演示: %s\n", c_style_str);
string::data:获取字符串数据指针(C++11后与c_str几乎无区别,早期无末尾'\0')

string::data参考文档,基本与第一个介绍的c_str()没多大区别:
cpp
string str = "Hello World! 123 Hello";
// 2. data:获取字符串数据指针(C++11后与c_str几乎无区别,早期无末尾'\0')
const char* data_ptr = str.data();
cout << "2. data 结果: " << data_ptr << endl;
// 说明:C++11标准后,data()返回的指针也带末尾'\0',和c_str()功能一致
// 区别仅在于语义:c_str强调"C风格字符串",data强调"原始数据"
string类中查找函数集合

经典函数string::find:从左到右查找子串/字符,返回首次出现的索引(没找到返回string::npos)

string::find参考文档,这个接口作用就是在string字符串中查找字符/子串,
而且由于版本发展,我们这里也会出现多个版本的find函数,但本质作用都是要去查找字符/子串,如果感兴趣,大家可以自己查阅参考文档:
cpp
string str = "Hello World! 123 Hello";
// 5. find:从左到右查找子串/字符,返回首次出现的索引(没找到返回string::npos)
size_t find_pos = str.find("Hello"); // 查找子串"Hello"
if (find_pos != string::npos) {
cout << "5. find 找到'Hello'的位置: " << find_pos << endl; // 输出: 0
}
find_pos = str.find("Test"); // 查找不存在的子串
cout << " find 没找到'Test'的返回值: " << (find_pos == string::npos ? "npos" : to_string(find_pos)) << endl;
// 6. rfind:从右到左查找,返回最后一次出现的索引
size_t rfind_pos = str.rfind("Hello");
cout << "6. rfind 找到最后一个'Hello'的位置: " << rfind_pos << endl; // 输出: 15
// 7. find_first_of:查找指定字符集中任意字符的出现位置
//可以看做find_any_of,作用是找到所有字符。
//这个名字可能有点问题,但这个接口用的不多
size_t first_of_pos = str.find_first_of("12345"); // 找'1'/'2'/'3'/'4'/'5'中出现的位置
cout << "7. find_first_of 找到数字的位置: " << first_of_pos << endl; // 输出: 13
// 8. find_last_of:查找指定字符集中任意字符的最后一次出现位置
//同7
size_t last_of_pos = str.find_last_of("lo"); // 找'l'或'o'最后出现的位置
cout << "8. find_last_of 找到'l/o'最后位置: " << last_of_pos << endl; // 输出: 18(第二个Hello的'o')
// 9. find_first_not_of:查找第一个不在指定字符集中的字符位置
string num_str = "12345abc678";
size_t first_not_of_pos = num_str.find_first_not_of("0123456789");
cout << "9. find_first_not_of 找到非数字的位置: " << first_not_of_pos << endl; // 输出: 5
// 10. find_last_not_of:查找最后一个不在指定字符集中的字符位置
size_t last_not_of_pos = num_str.find_last_not_of("0123456789");
cout << "10. find_last_not_of 找到最后一个非数字的位置: " << last_not_of_pos << endl;
// 输出: 7
string::substr:截取子串

string::substr参考文档,这个接口可以获取我们要从哪个位置开始的、多长的子串(参数1:起始索引,参数2:截取长度,缺省则到末尾):
cpp
string str = "Hello World! 123 Hello";
string sub1 = str.substr(6, 5); // 从索引6开始,截取5个字符
cout << "11. substr 结果1: " << sub1 << endl; // 输出: World
string sub2 = str.substr(13); // 从索引13开始,截取到末尾
cout << " substr 结果2: " << sub2 << endl; // 输出: 123 Hello
string::compare:比较两个字符串

string::compare参考文献,这个接口作用是比较两个字符串
返回值:0=相等,<0=当前串小,>0=当前串大
cpp
string str_a = "Apple";
string str_b = "Banana";
string str_c = "Apple";
int cmp_ab = str_a.compare(str_b);
int cmp_ac = str_a.compare(str_c);
cout << "12. compare 结果: " << endl;
cout << " Apple vs Banana: " << cmp_ab << "(<0表示Apple更小)" << endl; // 输出负数
cout << " Apple vs Apple: " << cmp_ac << "(=0表示相等)" << endl; // 输出0
getline (string)函数:得到一行的字符串内容

getline (string)参考文档,string字符串在使用cin输入数据时,有一个缺陷:遇到 ' '(空格)后才会终止读取(可以传第三个参数来改变这个终止flag):
cpp
#include <iostream>
#include <string>
int main ()
{
std::string name;
std::cout << "输入你的名字:";
//通常情况下,传入第一个参数是cin流(输入流),第二个才是string字符串。
std::getline (std::cin,name);
std::cout << "Hello, " << name << "!\n";
//特殊情况下,可以改变输入终止的flag
//遇到 '*'时停止读取
std::getline(std::cin,name,'*')
std::cout << "Hello, " << name << "!\n";
return 0;
}
本篇到这里就结束了,喜欢文章的小伙伴可以关注一下彩妙,我们下一篇再见~

