hello~ 很高兴见到大家! 这次带来的是C++中关于STL-string容器的使用这部分的一些知识点,如果对你有所帮助的话,可否留下你的三连呢? 个 人 主 页: 默|笙

STL(Standard Template Library,标准模板库) 是 C++ 标准库的重要组成部分,提供了通用的模板类和函数,用于实现数据结构和算法。它的核心思想是泛型编程,通过模板(Template)让代码具备高度复用性。

string:
定义: std :: string是c++标准库提供的动态字符串类(位于头文件 < string> 中),它封装了对字符序列的底层操作,以成员函数和运算符重载为用户提供了一套安全、便捷的接口。




//默认构造
string s1;
cout << "s1:" << s1 << endl;
s1 = "abcdefg";
//拷贝构造
string s2 = s1;//string s2(s1);
//子串构造
string s3(s1, 2);
//c风格
string s4("abc\0defg");
//从缓冲区
string s5("abc\0defg", 6);
//填充
string s6(5, 'a');
//范围
string s7(s2.begin(), s2.end());
cout << "s2:"<< s2 << endl;
cout << "s3:" << s3 << endl;
cout << "s4:" << s4 << endl;
cout << "s5:" << s5 << endl;
cout << "s6:" << s6 << endl;
cout << "s7:" << s7 << endl;执行结果:


析构函数会在 std::string 对象声明周期结束时(如离开作用域,被显式删除),会自动调用析构函数,无需手动干预,仅作了解即可。

string s1("abcdefg");
string s2;
cout << "s2:" << s2 << endl;
//string,自赋值是安全的(s2 = s2)
s2 = s1;
cout << "string:"<< "s2:" << s2 << endl;
//c_string
s2 = "abc\0defg";
cout << "string_c:" << "s2:" << s2 << endl;
//character
s2 = 'a';
cout << "character:" << "s2:" << s2 << endl;执行结果:

迭代器:在 C++ 中,迭代器(Iterator) 是一种行为类似于指针的对象,它提供了一种统一的方式来遍历和操作容器(如 std::vector、std::list、std::map 等)中的元素,而无需暴露容器的底层实现细节。 意义:


string s1 = "abcdefg";
string::iterator it1 = s1.begin();
string::const_iterator it1 = s1.begin();
string::const_iterator it1 = s1.cbegin();
string::reverse_iterator it3 = s1.rbegin();
string::const_reverse_iterator it3 = s1.rbegin();
string::const_reverse_iterator it3 = s1.crbegin();关于常量迭代器:关于新的类型const_iterator与const_reverse_iterator,它们限制只能对“指向”的元素进行只读访问,而不是指它本身不可修改(const iterator 是本身不可修改)。它们能够很好的保护数据。

//正向
cout << "正向:" << endl;
string::iterator it1 = s1.begin();
while (it1 != s1.end())
{
cout << *it1 << " ";
it1++;
}
cout << endl;
//反向
cout << "反向" << endl;
string::reverse_iterator it2 = s1.rbegin();
while (it2 != s1.rend())
{
cout << *it2 << " ";
it2++;
}执行结果:

string s1 = "abcdefg";
//下标 + []
for (size_t i = 0; i < s1.size(); i++)
{
cout << s1[i] << endl;
} string s1 = "abcdefg";
//迭代器
//[begin(), end())
string::iterator it1 = s1.begin();
while (it1 != s1.end())
{
(*it1)++;
++it1;
}
cout << s1 << endl;对于 string 而言,下标 + [] 的确更加直白简单,但是对于其他容器如链表(空间一般不连续),下标 + [] 不再适用,而迭代器适用于一切容器,是容器的主流遍历方式。
在c/c++早期,auto的含义是:使用 auto 修饰的变量,是具有自动存储器的局部变量。后来在 c++11中,它被赋予新的含义:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量的类型必须由编译器在编译时期经过推导而得。


int x = 10;
int& y = x;
auto z1 = y;//auto推演的是y本身的int类型,而非int&类型
z1++;
cout << y << endl;
auto& z2 = y;//在声明引用类型时,要加上&
z2++;
cout << y << endl;执行结果:

auto x = 5, y = 10; // 合法:x 和 y 均为 int
auto a = 1, b = 3.14; // 错误:int 和 double 类型不匹配,编译报错
//范围 for
for (auto e : s1)//e是容器元素的别名,可以随便换,但一般用e
{
e++;
cout << e;
}
vs里面,除了第一次,后续都是 1.5 倍扩容。 gcc里面,2倍扩容。
请求字符串减少其容量以适应其实际大小。
缩容代价很大,需重新分配内存:它无法直接缩小原有空间,只能去申请一块适应字符串大小的新的空间,然后将原内容拷贝到新的空间中,再释放原有空间,最后让string的内部指针指向新的空间。是一种用时间换空间的做法,一般不会这样做。
将字符串调整为n个字符的长度。

string s1 = "abcdefg";
//初始值:
cout << "初始值:" << endl;
cout << "s1:" << s1 << endl;
cout << "capacity:" << s1.capacity() << endl;
cout << "size:" << s1.size() << endl;
//改变大小(增)且不指定:
cout << "改变大小(增)且不指定:" << endl;
s1.resize(100);
cout << "s1:" << s1 << endl;
cout << "capacity:" << s1.capacity() << endl;
cout << "size:" << s1.size() << endl;
//改变大小(减):
cout << "改变大小(减):" << endl;
s1.resize(4);
cout << "s1:" << s1 << endl;
cout << "capacity:" << s1.capacity() << endl;
cout << "size:" << s1.size() << endl;
//补充:改变大小(增)且指定:
cout << "补充:改变大小(增)且指定:" << endl;
s1.resize(10, '#');
cout << "s1:" << s1 << endl;
cout << "capacity:" << s1.capacity() << endl;
cout << "size:" << s1.size() << endl;执行结果:

请求调整字符串容量,用于预先分配内存,以避免后续操作频繁分配内存,从而提高性能。扩容靠谱,缩容不靠谱。

它会将容量调整为至少 n 个字符,但不会改变字符串的长度。

返回字符串 pos 索引处字符的引用(非 const 限定的字符串可对其进行修改)。

功能与 operator[] 一样,不过它在处理越界时会抛异常。

void stirng_test06()
{
string s1 = "abcdefg";
s1.at(25);
}
int main()
{
try
{
stirng_test06();
}
catch (const exception& e)
{
cout << e.what() << endl;
}
return 0;
}结果:




通过在当前字符串的末尾添加其他字符来拓展字符串。
//string
string s0 = "abcdefg";
string s1 = "###";
s0 += s1;
cout << s0 << endl;
//c-string
string s2 = "abcdefg";
const char* str = "###";
s2 += str;
cout << s2 << endl;
//character
string s3 = "abcdefg";
s3 += '#';
cout << s3 << endl;结果:

追加内容,相比于operator +=,功能更加丰富,但其实平常用得不多。

在尾部插入一个字符。

整体替换内容,相比于operator =,功能更加丰富,但其实平常用得不多。

在索引为 pos 的值前插入字符或字符串。一般记住一个插入字符一个插入字符串的就行了。

string s1 = "abcdefg";
//字符串
s1.insert(0, "###");
cout << s1 << endl;
//字符
s1.insert(0, 1, '!');
cout << s1 << endl;
s1.insert(s1.begin(), '$');
cout << s1 << endl;结果:

insert谨慎使用,涉及底层数据移动,效率低下,时间复杂度可达O(N)。
删除部分字符串,减少字符串长度。

string s1 = "abcdefg";
//从索引为1的字符开始删,删一个
s1.erase(1, 1);
cout << s1 << endl;
//从索引为1的字符开始删,删完为止
s1.erase(1);
cout << s1 << endl;erase:谨慎使用,涉及底层数据移动,效率低下,时间复杂度可达O(N)。
用来替换字符串的一部分。

string s1 = "abcdefg";
s1.replace(1, 3, "#");
cout << s1 << endl;结果:

replace:谨慎使用,涉及底层数据移动,效率低下,时间复杂度可达O(N)。
交换,要注意 str 类型是 string& 而不是 const string&。

底层实现类似于:

算法库里面也有一个swap函数,但是不要去使用它,因为使用它的代价很大。它要实例化三次。

删掉字符串最后一个字符,使长度减 1。

返回一个指向数组的指针,该数组包含一个以’\0’结尾的字符序列,即c字符串。


string filename("Test.cpp");
FILE* fout = fopen(filename.c_str(), "r");
if (fout == nullptr)
{
cout << "fopen fail" << endl;
return;
}c++11以后,功能与c_str()完全相同。
用于获取容器当前使用的内存分配器。

拷贝当前对象的一部分到 s 所指向的数组中,从 pos(起始位置) 开始拷贝,最多拷贝 len 个字符,返回值是实际拷贝的字符数。

一般使用之后substr()来进行拷贝,这个用得很少。
从当前字符串对象中提取子串,并通过拷贝构造返回一个新的 string 对象。


查找当前字符串对象的字符或者是子字符串。


查找当前字符串对象的字符或者是子字符串。相比于find(),用法差不多,不过它是倒着从后往前找。

给定一个字符串或单个字符参考集合 s 或 c,在当前字符串对象里查找第一个在参考集合里面的字符,并返回它的索引。

功能和 find_first_of(s/c, pos)差不多,不过它是倒着从后往前查找。
给定一个字符串或单个字符参考集合 s 或 c,在当前字符串对象里面查找第一个不在参考集合里面的字符,并返回它的索引。

功能和 find_first_not_of(s/c, pos)差不多,不过与之相比,它是倒着从后往前查找。
用来比较字符串,不过很少用到它,因为非成员函数里重载了用来比较的运算符,了解一下。


连接字符串并返回新的字符串,并且不会改变字符串彼此的值。

成员函数的都有一个隐藏的参数:const string& this,为了支持第一个参数为非string类型(如const char*),operator+需要被重载为非成员函数。之后的关系运算符重载函数重载为非成员函数也是这个原因。
其重载了所有的关系运算符。

交换两个字符串的值。

它存在的原因就是可以避免调用算法库里代价大的swap函数,已经准备好的函数的优先级是大于没有实例化的模板函数的。
让 string类对象可以像内置类型一样输入输出。
从输入流中读取一行文本(遇到’\n’停止),并将其存储到字符串对象 str 中,类似cin。使用依赖<string>头文件。

它与 cin 的区别:
string s1;
getline(cin, s1);
cout << "s1:" << s1 << endl;
string s2;
cin >> s2;
cout << "s2:" << s2 << endl;
#pragma once
#include<iostream>
#include<string.h>
#include<assert.h>
#include<vector>
using namespace std;
//解决命名冲突-->命名空间
namespace mosheng
{
class string
{
public:
typedef char* iterator;
typedef const char* const_iterator;
//begin()
iterator begin();
const_iterator begin()const;
//end()
iterator end();
const_iterator end()const;
////默认构造函数
//string();
////c风格字符串构造(带参构造)
//string(const char* str);
//两个构造函数合并成全缺省构造函数
string(const char* str = "");
//拷贝构造
string(const string& s);
//swap
void swap(string& s);
//赋值重载函数
string& operator=(string tmp);
//析构函数
~string();
//c_str
const char* c_str()const;
//size函数
size_t size()const;
//operator[]重载
//可读也可写
char& operator[](size_t i);
//只可读
const char& operator[](size_t i)const;
//扩容
void reserve(size_t x);
//尾插
void push_back(char ch);
void append(const char* str);
//>>与<<
string& operator+=(char ch);
string& operator+=(const char* str);
//在指定位置上插入
string& insert(size_t pos, char ch);
string& insert(size_t pos, const char* str);
//删除指定位置
//void erase(size_t pos);
string& erase(size_t pos = 0, size_t len = npos);
//尾删
void pop_back();
//查找
size_t find(char ch, size_t pos = 0)const;
size_t find(const char* str, size_t pos = 0)const;
//获取子串
string substr(size_t pos, size_t len = npos)const;
//关系运算符重载
bool operator<(const string& s)const;
bool operator<=(const string& s)const;
bool operator>(const string& s)const;
bool operator>=(const string& s)const;
bool operator==(const string& s)const;
bool operator!=(const string& s)const;
//清理
void clear();
private:
//类似于顺序表
//不能用 const char*,我们是要修改字符串数组上的内容的
char* _str = nullptr;
size_t _size = 0;
size_t _capacity = 0;
public:
static const size_t npos;
};
ostream& operator<<(ostream& out, const string& s);
istream& operator>>(istream& in, string& s);
istream& getline(istream& in, string& s, char delim = '\n');
}#define _CRT_SECURE_NO_WARNINGS
#include"string.h"
//如何进行具体的实现?
//法一:mosheng::string::string()
// mosheng::string::string(const char* str)
//法二:定义命名空间:
// 多个文件可以定义同一个命名空间,不会冲突,多个文件的名称相同
// 命名空间编译器会认为是同一个命名空间
namespace mosheng
{
const size_t string::npos = -1;
//begin()
//iterator前也要加string,突破类域使用
string::iterator string::begin()
{
return _str;
}
string::const_iterator string::begin()const
{
return _str;//返回值自动转换为 const char*类型
}
//end()
string::iterator string::end()
{
return _str + _size;
}
string::const_iterator string::end()const
{
return _str + _size;
}
////默认构造函数
//string::string()
// //通过字符串指针打印字符,首先是对指针解引用
// //空指针不能被解引用,程序会崩溃
// //:_str(nullptr)
//
// //待会儿可能会开多个,用 new[]对应
// :_str(new char[1]{'\0'})
// ,_capacity(0)
// ,_size(0)
//{}
////带参构造函数
//string::string(const char* str)
// //涉及到权限放大问题,而且怎么能是单纯的指向str字符串
// 需要申请一个独立的空间
// //:_str(str)
// //注意要给'\0'留个空间
// //调用了三次 strlen 不好,代价大
// :_str(new char[strlen(str) + 1])
// ,_size(strlen(str))
// ,_capacity(strlen(str))
//{
// //strcpy会把'\0'一起给拷贝过来
// strcpy(_str, str);
//}
//带参构造函数
string::string(const char* str)
//涉及到权限放大问题,而且怎么能是单纯的指向str字符串
// 需要申请一个独立的空间
//:_str(str)
//注意要给'\0'留个空间
: _size(strlen(str))
{
//放到里面去,既不会因为初始化列表初始顺序出现问题代价也小
_capacity = _size;
_str = new char[_size + 1];
//strcpy会把'\0'一起给拷贝过来
//strcpy(_str, str);
memcpy(_str, str, _size + 1);
}
//拷贝构造(深拷贝)
//string::string(const string& s)
//{
// //记得要多开一个
// _str = new char[s._capacity + 1];
// memcpy(_str, s._str, s._size + 1);
// _size = s._size;
// _capacity = s._capacity;
//}
void string::swap(string& s)
{
//为了正常交换,需要给成员变量一个缺省值,编译器可能不会处理
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
//拷贝构造(现代写法)
string::string(const string& s)
{
string tmp(s._str);
swap(tmp);
}
////赋值重载函数(传统写法)
//string& string::operator=(const string& s)
//{
// if (this != &s)
// {
// char* tmp = new char[s._capacity + 1];
// memcpy(tmp, s._str, s._size + 1);
// delete[] _str;
// _str = tmp;
// _size = s._size;
// _capacity = s._capacity;
// }
// return *this;
//}
//赋值重载函数(现代写法)
string& string::operator=(string tmp)
{
swap(tmp);
return *this;
}
//析构函数
string::~string()
{
//与new[]对应
delete[] _str;
_str = nullptr;
_size = 0;
_capacity = 0;
}
//c_str
const char* string::c_str()const
{
return _str;
}
//size函数
size_t string::size()const
{
return _size;
}
//operator[]重载
// 可读也可写
char& string::operator[](size_t i)
{
assert(i < _size);
return _str[i];
}
//只可读
const char& string::operator[](size_t i)const
{
assert(i < _size);
return _str[i];
}
//扩容
void string::reserve(size_t n)
{
if (n > _capacity)
{
//cout << "void string::reserve(size_t n)" << endl;
//是希望存储 n 个有效字符,还要为'\0'预留一个
char* str = new char[n + 1];
//strcpy只copy到第一个'\0',会出现问题
//strcpy(str, _str);
memcpy(str, _str, _size + 1);
//释放旧空间
delete[] _str;
//_str指向新空间
_str = str;
_capacity = n;
}
}
//尾插
void string::push_back(char ch)
{
if (_size >= _capacity)
{
size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
reserve(newcapacity);
}
_str[_size] = ch;
_size++;
_str[_size] = '\0';
}
void string::append(const char* str)
{
size_t len = strlen(str);
if (_size + len > _capacity)
{
size_t newcapacity = 2 * _capacity > (_capacity + len) ? 2 * _capacity : _capacity + len;
reserve(newcapacity);
}
//strcpy(_str + _size, str);
memcpy(_str + _size, str, len + 1);
_size = _size + len;
}
string& string::operator+=(char ch)
{
push_back(ch);
return *this;
}
string& string::operator+=(const char* str)
{
append(str);
return *this;
}
//<< 与 >>
ostream& operator<<(ostream& out, const string& s)
{
//有坑,关于'\0'
//out << s.c_str();
for (int i = 0; i < s.size(); i++)
{
if (s[i] != '\0')
out << s[i];
}
return out;
}
//在指定位置上插入
string& string::insert(size_t pos, char ch)
{
assert(pos <= _size);
if (_size >= _capacity)
{
size_t newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
reserve(newcapacity);
}
//int end = size;
//还是用无符号整数类型
size_t end = _size + 1;
while (end >= pos + 1)
{
_str[end] = _str[end - 1];
end--;
}
_str[pos] = ch;
_size++;
return *this;
}
string& string::insert(size_t pos, const char* str)
{
size_t len = strlen(str);
if (_size + len > _capacity)
{
size_t newcapacity = 2 * _capacity > (_capacity + len) ? 2 * _capacity : _capacity + len;
reserve(newcapacity);
}
size_t end = _size + len;
while (end >= pos + len)
{
_str[end] = _str[end - len];
end--;
}
memcpy(_str + pos, str, len);
_size += len;
return *this;
}
//删除指定位置
/*void string::erase(size_t pos)
{
size_t begin = pos;
while (pos <= _size)
{
_str[pos] = _str[pos + 1];
pos++;
}
_size--;
}*/
string& string::erase(size_t pos, size_t len)
{
assert(pos <= _size);
if (len == npos || len >= _size - pos)
{
_str[pos] = '\0';
_size = pos;
}
else
{
/*size_t begin = pos;
while (pos + len <= _size)
{
_str[pos] = _str[pos + len];
pos++;
}*/
size_t i = pos + len;
memmove(_str + pos, _str + i, _size - i + 1);
_size -= len;
}
return *this;
}
//尾删
void string::pop_back()
{
assert(_size > 0);
_size--;
_str[_size] = '\0';
}
//查找
size_t string::find(char ch, size_t pos)const
{
assert(pos <= _size);
for (size_t i = pos; i < _size; i++)
{
if (_str[i] == ch)
return i;
}
return npos;
}
size_t string::find(const char* str, size_t pos)const
{
assert(pos <= _size);
const char* find = strstr(_str + pos, str);
if (find != nullptr)
{
//指针相减可以得到中间的字符数量
return find - _str;
}
return npos;
}
//获取子串
string string::substr(size_t pos, size_t len)const
{
if (len == npos || _size - pos < len)
{
len = _size - pos;
}
string ret;
ret.reserve(len);
//memcpy(ret._str, _str + pos, len);
for (int i = 0; i < len; i++)
{
ret += _str[pos + i];
}
//初始要调用两次拷贝构造
//和二为一,不生成临时对象,ret直接拷贝构造到后面的对象上去
//vs2022和三为一,ret跟后面的对象的地址相同,ret是后面对象的别名,不需要调用拷贝构造
return ret;
}
bool string::operator<(const string& s)const
{
size_t i1 = 0, i2 = 0;
while (i1 < _size && i2 < s._size)
{
if (_str[i1] < s._str[i2])
{
return true;
}
else if (_str[i1] > s._str[i2])
{
return false;
}
i1++;
i2++;
}
return _size < s._size;
}
bool string::operator==(const string& s)const
{
size_t i1 = 0, i2 = 0;
while (i1 < _size && i2 < s._size)
{
if (_str[i1] != s._str[i2])
{
return false;
}
i1++;
i2++;
}
if (_size == s._size)
{
return true;
}
return false;
}
bool string::operator<=(const string& s)const
{
if (*this < s || *this == s)
return true;
return false;
}
bool string::operator>(const string& s)const
{
if (!(*this <= s))
return true;
return false;
}
bool string::operator>=(const string& s)const
{
if (!(*this < s))
return true;
return false;
}
bool string::operator!=(const string& s)const
{
if (!(*this == s))
return true;
return false;
}
//清理
void string::clear()
{
_size = 0;
_str[0] = '\0';
}
//往往需要扩容多次,还有空间的浪费
//istream& operator>>(istream& in, string& s)
//{
// s.clear();
// char ch = in.get();
// //cin 与 scanf会自动忽略掉空格与换行,读不到
// //in >> ch;
// while (ch != ' '&& ch != '\n')
// {
// s += ch;
// //in >> ch;
// ch = in.get();
// }
// return in;
//}
istream& operator>>(istream& in, string& s)
{
s.clear();
char buff[128];
int i = 0;
char ch = in.get();
while (ch != ' ' && ch != '\n')
{
buff[i++] = ch;
//存储的有效字符为127个,还剩一个用来存储'\0'
if (i == 127)
{
buff[i] = '\0';
s += buff;
i = 0;
}
ch = in.get();
}
if (i > 0)
{
buff[i] = '\0';
s += buff;
}
return in;
}
istream& getline(istream& in, string& s, char delim)
{
s.clear();
char buff[128];
int i = 0;
char ch = in.get();
while (ch != delim)
{
buff[i++] = ch;
//存储的有效字符为127个,还剩一个用来存储'\0'
if (i == 127)
{
buff[i] = '\0';
s += buff;
i = 0;
}
ch = in.get();
}
if (i > 0)
{
buff[i] = '\0';
s += buff;
}
return in;
}
}#define _CRT_SECURE_NO_WARNINGS
#include"string.h"
//这里的命名空间是为了封装,若在命名空间之外也有一个
//test_string,它们之间不会冲突
namespace mosheng
{
void test_string1()
{
string s1;
//cout << s1 << endl;
cout << s1.c_str() << endl;
const string s2("hello world!");
cout << s2.c_str() << endl;
/*for (size_t i = 0; i < s2.size(); i++)
{
s2[i]++;
cout << s2[i] << " ";
}*/
cout << endl;
for (auto ch : s2)
{
cout << ch << " ";
}
cout << endl;
string::const_iterator it1 = s2.begin();
/*while (it1 != s2.end())
{
cout << *it1 << " ";
it1++;
}*/
cout << endl;
}
void test_string02()
{
string s1("hello world!");
s1.push_back('#');
cout << s1.c_str() << endl;
s1.append("abc");
cout << s1.c_str() << endl;
s1 += "###";
cout << s1.c_str() << endl;
cout << s1 << endl;
//关于'\0'的坑
s1 += '\0';
s1 += '\0';
s1 += '#';
s1 += "yyyyyyyyyyyyyyyyyyyyyyyyy";
cout << s1 << endl;
cout << s1.c_str() << endl;
}
void test_string03()
{
string s1("hello world!");
s1.insert(0, '#');
cout << s1 << endl;
s1.insert(0, "!!!");
cout << s1 << endl;
s1.erase(0, 1);
cout << s1 << endl;
s1.erase(5, 2);
cout << s1 << endl;
s1.pop_back();
cout << s1 << endl;
}
void test_string04()
{
string s1("abcdefg");
size_t find = s1.find('c');
cout << find << endl;
cout << s1.find("efg") << endl;
}
void split_url(const string& url)
{
size_t i1 = url.find(':');
if (i1 != string::npos)
{
cout << url.substr(0, i1) << endl;
}
size_t i2 = i1 + 3;
size_t i3= url.find('/', i2);
if (i3 != string::npos)
{
cout << url.substr(i2, i3) << endl;
cout << url.substr(i3 + 1) << endl;
}
}
void test_string05()
{
string url1 = "http://legacy.cplusplus.com/reference/string/string/";
string url2 = "https://yuanbao.tencent.com/chat/naQivTmsDa/43735652-b5e3-11ef-bcaa-c6162ee89a56?yb_channel=3003";
string url3 = "https://legacy.cplusplus.com/reference/vector/vector/";
split_url(url1);
split_url(url2);
split_url(url3);
}
void test_string06()
{
string s1("hello"), s2("hello");
string s3("hellox"), s4("hello");
string s5("hello"), s6("hellox");
cout << (s1 < s2) << endl;
cout << (s3 < s4) << endl;
cout << (s5 < s6) << endl;
}
void test_string07()
{
string s1;
string s2("hello");
//cin >> s1 >> s2;
getline(cin, s1);
s2 = s1;
cout << s1 << " " << s2;
}
}
int main()
{
//mosheng::test_string02();
// mosheng::test_string1();
/*cout << typeid(mosheng::string::iterator).name() << endl;
cout << typeid(std::string::iterator).name() << endl;*/
//mosheng::test_string03();
//mosheng::test_string04();
//mosheng::test_string06();
mosheng::test_string07();
return 0;
}今天的分享就到此结束啦,如果对读者朋友们有所帮助的话,可否留下宝贵的三连呢~~ 如果可以, 那就让我们共同努力, 一起走下去!