一、resize()
void test7()
{
string s("hello world");
s.resize(5); //改变长度
s.resize(20,'x'); //改变空间大小
}
int main()
{
test7();
return 0;
}
二、string常用函数接口
1.打印
2.+=、push_back、append
3.迭代器,读写;s.begin()、s.end()、s.rbegin()、s.rend()
4. s.size()、s.length()、s.capacity()
5.s.reserve(100)、s.resize(100,'x')
6.s.insert(0,"x")、s.insert(s.begin(),"x")
7.s.erase(2,3)
8.s.substr(2,3) //从下标为2开始,往后打印3个
9.< >,比较的是字符的ascii码
10.getline(cin,s1),遇到换行结束;cin>>s1,遇到换行或空格结束
#include <iostream>
#include <string>
using namespace std;
//1.常规用法
void test1()
{
string s1;
string s2("hello");
string s3(s2); //拷贝构造
string s4("hello",2); //he,打印前两个
string s5("hello",1,2); //el,从第二个开始打印
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;
cout << s5 << endl;
}
//2.读和写
void test2()
{
string s1("hello");
s1 += ' ';
s1 += "world";
cout << s1 << endl;
//写
for (size_t i=0; i<s1.size(); i++)
{
s1[i] += 1;
}
//读
for (size_t i = 0; i < s1.size(); i++)
{
cout << s1[i]<<' ';
}
cout << endl;
//迭代器 写
string::iterator it = s1.begin(); //可将it看作指针
while (it != s1.end()) //end指向‘o’后面的位置
{
*it -= 1;
++it;
}
//迭代器 读
it = s1.begin();
while (it != s1.end())
{
cout << *it << " ";
++it;
}
cout << endl;
}
//3.倒着遍历
void test3()
{
string s1("hello");
string::reverse_iterator rit = s1.rbegin();
while (rit != s1.rend())
{
cout << *rit << " ";
rit++;
}
}
//4.将字符串格式转换为整型
int string2int_zheng(const string& str)
{
int val = 0;
string::const_iterator it = str.begin();
while (it != str.end())
{
val *= 10;
val += (*it - '0');
++it;
}
return val;
}
int string2int_fan(const string& str)
{
//将字符串格式转换为整型倒序
int val = 0;
string::const_reverse_iterator rit = str.rbegin();
while (rit != str.rend())
{
val *= 10;
val += (*rit - '0');
++rit;
}
return val;
}
void test4()
{
string s1("12345");
int ret1 = string2int_zheng(s1);
cout << ret1 << endl;
int ret2 = string2int_fan(s1);
cout << ret2 << endl;
}
//5.长度、空间
void test5()
{
string s1("hello world");
cout << s1.size() << endl; //11
cout << s1.length() << endl; //11
cout << s1.capacity() << endl; //15
s1 += "123456";
cout << s1.capacity() << endl; //31
s1.clear();
cout << s1.capacity() << endl; //31,只是把字符串清空,空间没有释放
}
//6.改变空间和长度
void test6()
{
string s;
s.reserve(100); //reserve只会改变空间
//s.resize(100); //resize改变空间和长度
//s.resize(100,'x');
size_t sz = s.capacity();
cout << "making s grow\n";
for (int i = 0;i<100;i++)
{
s.push_back('c');
if (sz != s.capacity())
{
sz = s.capacity();
cout << "capacity changed:" << sz << '\n';
}
}
}
//7.插入和删除
void test8()
{
string s;
//尾部插入
s.push_back('x');
s.append("123456");
s += 'y';
s += "abc";
cout << s << endl; //x123456yabc
//中间插入
s.insert(s.begin(),'0');//头部插入'0',0x123456yabc
cout << s << endl;
s.insert(0, "2"); //头部插入"2",20x123456yabc
cout << s << endl;
s.insert(2, "w"); //下标为2处插入"w",20wx123456yabc
cout << s << endl;
//删除
s.erase(2,3); //下标为2处开始删除3个,2023456yabc
cout << s << endl;
s.erase(2, 10); //删除长度大于字符串长度,删除到尾部截止,20
cout << s << endl;
}
//8.find+substr
void test8()
{
string url("https://mp.csdn.net/mp.blog"); //协议-域名-资源名称
size_t i1 = url.find(':');
if (i1 != string::npos)
{
cout << url.substr(0, i1) << endl; //从下标0开始,长度为i1
}
size_t i2 = url.find('/',i1+3); //找'/',从i1+3位置开始
if (i2 != string::npos)
{
cout << url.substr(i1 + 3, i2 - i1 - 3) << endl; //从i1 + 3下标开始,长度为i2 - i1 - 3
}
cout << url.substr(i2+1) << endl;
}
//9.>、<
void test9()
{
string s1("abcd");
string s2("bcde");
cout << (s1<s2) << endl; //比较的是ascii,'a'的小于'b',输出为真
cout << (s1 < "bcde") << endl;
cout << ("abcd" < s2) << endl;
}
//10.getline
void test10()
{
string str;
//cin >> str; //遇到空格或者换行就结束,无法输入"hello world",空格输入不了
getline(cin,str); //只有遇到换行才结束
}
int main()
{
test8();
return 0;
}
三、模拟实现string
namespace bit
{
class string
{
public:
typedef char* iterator;
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}
string(const char* str = "")
{
_size = strlen(str);
_capacity = _size;
_str = new char[_capacity +1];
strcpy(_str,str);
}
~string()
{
delete[] _str;
_str = nullptr;
_size = _capacity = 0;
}
//s1=s2,现代写法
string& operator=(const string& s)
{
if (this != &s)
{
string tmp(s);
swap(_str,tmp._str);
}
return *this;
}
//s1=s2,传统写法
string& operator=(string s)
{
if (this != &s)
{
char* tmp = new char[strlen(s._str)+1];
strcpy(tmp,s._str);
delete[] _str;
_str = tmp;
}
return *this;
}
size_t size() const
{
return _size;
}
size_t capacity() const
{
return _capacity;
}
char& operator[](size_t i)
{
assert(i<_size);
return _str[i];
}
const char& operator[](size_t i) const
{
assert(i < _size);
return _str[i];
}
char* c_str()
{
return _str;
}
//
void reserve(size_t n)
{
char* newstr = new char[n + 1]; //开辟出新空间,给'\0'多开辟一块空间
strcpy(newstr, _str);
delete[] _str;
_str = newstr;
_capacity = n;
}
//尾部增加一个字符
void push_back(char ch)
{
if (_size == _capacity)
{
size_t newcapacity = _capacity == 0 ? 2 : _capacity * 2;
reserve(newcapacity);
}
_str[_size] = ch;
_size++;
_str[_size] = '\0';
}
//尾部增加字符串
void append(const char* str)
{
size_t len = strlen(str);
if (_size + len > _capacity)
{
size_t newcapacity = _size + len;
reserve(newcapacity);
}
strcpy(_str+_size,str);
_size += len;
}
//+=
string& operator+=(const char ch) //尾部插入字符
{
this->push_back(ch);
return *this;
}
string& operator+=(const char* ch) //尾部插入字符串
{
this->append(ch);
return *this;
}
//插入字符
void insert(size_t pos,char ch)
{
if (_size == _capacity)
{
size_t newcapacity = _capacity == 0 ? 2 : 2 * _capacity;
reserve(newcapacity);
}
int end = _size;
while (end != pos-1)
{
_str[end+1] = _str[end];
end--;
}
_str[pos] = ch;
_size++;
}
//插入字符串
void insert(size_t pos,const char* ch)
{
int len = strlen(ch);
if (len + _size > _capacity)
{
size_t newcapacity = len + _size;
reserve(newcapacity);
}
int end = _size;
while (end != pos-1)
{
_str[end + len] = _str[end];
end--;
}
for (size_t i = 0; i < len; i++)
{
_str[pos+i] = ch[i];
}
_size += len;
}
void resize(size_t n,char ch = '\0')
{
if (n < _size)
{
_str[n] = '\0';
_size = n;
}
else
{
if (n > _capacity)
{
reserve(n);
}
for (size_t i = _size; i < n; i++)
{
_str[i] = ch;
}
_size = n;
_str[_size] = '\0';
}
}
void erase(size_t pos,size_t len)
{
if (len >= _size - pos)
{
_str[pos] = '\0';
_size = pos;
}
else
{
size_t i = pos + len;
while (i <= _size)
{
_str[i - len] = _str[i];
i++;
}
_size -= len;
}
}
size_t find(char ch,size_t pos = 0)
{
for (size_t i = pos; i<_size; i++)
{
if (_str[i] == ch)
return i;
}
return npos;
}
size_t find(const char* str,size_t pos = 0)
{
char* p = strstr(_str,str);
if (p == nullptr)
{
return npos;
}
else
{
return p - _str;
}
}
bool operator<(const string& s)
{
int ret = strcmp(_str, s._str);
return ret < 0;
}
bool operator==(const string& s)
{
int ret = strcmp(_str, s._str);
return ret == 0;
}
bool operator<=(const string& s)
{
return *this < s || *this == s;
}
bool operator>=(const string& s)
{
return !(*this < s);
}
bool operator>(const string& s)
{
return !(*this <= s);
}
private:
char* _str;
size_t _size;
size_t _capacity;
static size_t npos;
};
ostream& operator<<(ostream& out,const string& s)
{
for (size_t i = 0; i < s.size(); ++i)
{
cout << s[i];
}
return out;
}
istream& operator>>(istream& in, string& s)
{
while (1)
{
char ch;
ch = in.get();
//getline: if (ch == '\n')
if (ch == ' ' || ch == '\n')
{
break;
}
else
{
s += ch;
}
}
return in;
}
void test1()
{
string s1;
string s2("hello");
cout << s1 << endl;
cout << s2 << endl;
cout << s1.c_str() << endl;
cout << s2.c_str() << endl;
//三种遍历方式
for (size_t i=0; i<s2.size(); ++i)
{
s2[i] += 1;
cout << s2[i] << " ";
}
cout << endl;
//迭代器方式实现
string::iterator it2 = s2.begin();
while (it2 != s2.end())
{
*it2 -= 1;
cout << *it2 << " ";
++it2;
}
cout << endl;
//范围for(由迭代器支持,最终会被编译器替换成迭代器)
for (auto e : s2)
{
cout << e << " ";
}
cout << endl;
}
void test2()
{
string s1("hello");
s1.push_back(' ');
s1.push_back('w');
s1.append("xxxxxxxxxx");
s1 += 'a';
s1 += "bcd";
cout << s1 << endl;
string s2;
s2 += "abcd";
s2 += ' ';
cout << s2 << endl;
}
void test3()
{
string s1("hello");
//s1.insert(0,'w');
s1.insert(1, "aaa");
cout << s1 << endl;
cout << s1.size() << endl;
cout << s1.capacity() << endl;
s1.resize(5);
cout << s1 << endl;
s1.resize(8,'x');
cout << s1 << endl;
cout << s1.size() << endl;
cout << s1.capacity() << endl;
}
void test4()
{
string s1;
cin >> s1;
cout << s1;
}
}
namespace bit
{
using namespace std;
class string
{
public:
string(const char* str = "")
:_str(new char[strlen(str)+1])
{
strcpy(_str,str);
}
size_t size()
{
return strlen(_str);
}
char& operator[](size_t i)
{
return _str[i];
}
//深拷贝strings2(s1),传统写法
string(const string& s)
:_str(new char[strlen(s._str) + 1])
{
strcpy(_str, s._str);
}
//深拷贝,现代写法
string(const string& s)
:_str(nullptr)
{
string tmp(s._str);
swap(_str,tmp._str);
}
~string()
{
delete[] _str;
_str = nullptr;
}
private:
char* _str;
};
void test()
{
string s1("hello");
//string s2;
for (size_t i =0; i<s1.size(); i++)
{
cout << s1[i] << endl;
}
}
}