目录
1.string容器
2.构造函数和析构函数的相关 *** 作
3.迭代器
4.容量相关
5.元素访问相关
6.元素遍历相关
7.字符串 *** 作
7.1 operator+=
7.2 append
7.3 push_back
7.4 insert && erase
7.5swap
8.string模拟实现
1.string容器
string容器是C++标准模板库提供的专门用来存储 *** 作字符串的容器。下边介绍了string容器的一些基本 *** 作,均参考于C++官方文档。
2.构造函数和析构函数的相关 *** 作3.迭代器#include
#include using namespace std; int main() { const char* arr = "world"; string s0("hello"); string s1(s0); string s2(s0,0,2); string s3(10,'a'); string s4(arr, 3); string s5(s0.begin(), s0.begin() + 3); ~string(); return 0; }
4.容量相关begin() 和end()
begin()和end()目前可以看成两个指针,begin()指向字符串的头部,end()指向字符串尾部的下一个位置,即 \0 的位置。我们可以使用begin()和end()进行遍历 *** 作和获取位置 *** 作。
rbegin(),rend()
rbegin()和rend()正好与上边的begin() 和end()相反,rbegin()指向字符串的尾部,即 \0 的位置,rbegin()指向字符串头部。
#include
#include using namespace std; int main() { string s0("hello world!"); string s1(s0.begin(), s0.end()); string s2(s0.rbegin(), s0.rend()); return 0; }
5.元素访问相关size:字符串中有效元素的个数,不包括size_t capacity() const;capcity:字符串底层顺序表的空间的大小 size_t size() const;此方法可以求字符串的长度,和C语言中length()方法相似
void resize (size_t n); void resize (size_t n, char c);此方法可以查看顺序表实际上内部容量,因为string是可以自己扩容的,所以他的容量一定比存储的字符串多,当拷贝的字符串大于capacity时,String底层动态扩容。
void reserve (size_t n );此函数作用是更新有效元素个数,当n
size && n capcity,则编译器会先申请一块大于n的空间,然后将原来字符串拷贝进去,使用参数c填充,再销毁原空间。 void clear();此方法可以调整顺序表的容量大小,不会修改有效元素个数,此函数作用是将字符串容量变为n个,当n大于capcity时正常扩容; 当n小于原来capcity且大于有效元素个数时(size),则缩减capcity; 当n小于有效元素个数时,编译器忽略这条指令。
bool empty() const;清空有效元素,但是不改变capcity大小
检测这个字符串是否为空,空则返回true,非空则返回false;
6.元素遍历相关operator[]
char& operator[] (size_t pos); const char& operator[] (size_t pos) const;
string底层就是一个字符数组,所以可以像访问数组一样使用[]访问字符串。
at
char& at (size_t pos); const char& at (size_t pos) const;
at和[]在使用效果方面完全一致,使用方法举例 cout << str.at(i);
区别:[]在越界访问时会触发assert断言,at会抛出异常,可供用户捕获。
7.字符串 *** 作 7.1 operator+=1.for循环
2.范围for
3.迭代器
#include
#include using namespace std; int main() { string s0("hello world!"); //for循环 for (int i = 0; i < s0.size(); i++) { cout << s0[i]; } cout << endl; //范围for for (auto e : s0) { cout << e; } cout << endl; //迭代器 string::iterator it = s0.begin(); while (it !=s0.end()) { cout << *it; it++; } cout << endl; return 0; } 结论:不同的方法都可以达到遍历效果。
7.2 append#include
#include using namespace std; int main() { string s0("hello world!"); string s1("aa"); const char* p = "***"; s1 += s0; s1 += p; s1 += '+'; cout << s1<
7.3 push_back#include
#include using namespace std; int main() { string s1("hello world!"); const char* s2 = "bye"; s1.append( s2, 10); s1.append(3,'c'); s1.append("hello"); cout << s1 << endl; return 0; }
7.4 insert && erase#include
#include using namespace std; int main() { string s1("hello world!"); const char* s2 = "bye"; s1.push_back('c'); cout << s1 << endl; return 0; }
7.5swap#include
#include using namespace std; int main() { string s1("hello world!"); s1.insert(6, "!!! ", 4); s1.erase(6,4); return 0; }
8.string模拟实现#include
#include using namespace std; int main() { string s1("hello world!"); string s2; s2.swap(s1); return 0; }
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
namespace str {
class string {
public:
typedef char* iterator;
typedef char* reverse_iterator;
//构造函数
string(const char* a="") {
if (a == nullptr) {
assert(false);
}
_size = strlen(a);
_str = new char[_size + 1];
strcpy(_str, a);
_capcity = _size;
}
string(size_t n,char s) {
_str = new char[n+1];
memset(_str,s,n);
*(_str + n) = '\0';
_size = n;
_capcity = n;
}
string(const string& s)
:_str(nullptr)
{
/*
浅拷贝,两个对象地址相同,不安全
_size = s._size;
_capcity = s._capcity;
_str=s._str;
*/
///解决方式:深拷贝//
string tmp(s._str);
this->swap(tmp);
}
~string() {
if (_str) {
delete[] _str;
_str = nullptr;
_size = 0;
_capcity = 0;
}
}
//赋值运算符重载
string& operator=(string s) {
swap(s);
return *this;
}
//迭代器
iterator begin() {
return this->_str;
}
iterator end() {
return _str + _size;
}
reverse_iterator rbegin() {
return _str+_size;
}
reverse_iterator rend() {
return _str;
}
//capcity相关
size_t size()const {
return _size;
}
size_t length()const {
return _size;
}
size_t capcity()const {
return _capcity;
}
bool empty()const {
if (_size == 0) {
return true;
}
return false;
}
void resize(size_t newsize,char s) {
size_t oldsize = size();
if (newsize < 0) {
assert(0);
}
if (newsize <= oldsize) {
_str[newsize] = '< _size);
return _str[index];
}
const char& operator[](size_t index)const {
assert(index < _size);
return _str[index];
}
/modify
void push_back(char s) {
append(1,s);
}
string& operator+=(const string& s) {
append(s._str);
return *this;
}
string& operator+=(const char* str) {
append(str);
return *this;
}
//insert erase swap
string& insert(size_t pos,const string& s) {
size_t len = strlen(s._str);
char* p=s._str;
if (len + _size >';
}
else {
if ( newsize > _capcity) {
reserve(newsize);
}
append(newsize - oldsize, s);
}
_size = newsize;
}
void reserve(size_t newsize) {
if (newsize > _capcity) {
char* tem = new char[newsize+1];
strcpy(tem,_str);
delete[] _str;
_str=tem;
_capcity = newsize;
}
}
//访问相关
//modify相关
string& append(size_t n,char a) {
if (n + _size > _capcity) {
reserve(n + _size);
}
memset(_str+_size, a, n);
_str[_size + n] = '\0';
_size = n + _size;
return *this;
}
string& append(const char* str) {
size_t len=strlen(str);
if (len + _size > _capcity) {
reserve(len + _size);
}
strcat(_str,str);
_size = len + _size;
return *this;
}
//Element acess
char& operator[](size_t index) {
assert(index <_size);
while (_str[pos] != '<<(ostream& _cout, const string& s)
{
_cout << s._str;
return _cout;
}
private:
char* _str;
size_t _size;
size_t _capcity;
static size_t npos;
};
size_t string::npos = -1;
void TestString1()
{
str::string s1;
str::string s2("hello");
str::string s3(s2);
str::string s4(10, 'A');
cout << s4.size() << std::endl;
cout << s2 << endl;
for (auto e : s3)
cout << e;
cout << endl;
auto it = s4.begin();
while (it != s4.end())
{
cout << *it;
++it;
}
cout << endl;
}
void TestString2()
{
str::string s("hello");
s.resize(10, '!');
std::cout << s << std::endl;
s.resize(7, '!');
}
void TestString3()
{
str::string s("abc.cpp");
str::string ret = s.substr(s.rfind('.') + 1);
cout << ret << endl;
}
}
int main() {
str::TestString1();
str::TestString2();
str::TestString3();
return 0;
}
') {
_str[pos] = _str[pos + 1];
}
return *this;
}
///string operator
size_t find(char ch, size_t pos = 0) {
for (size_t i = pos; i < _size; i++) {
if (ch==_str[i]) {
return i;
}
}
return npos;
}
size_t rfind(char ch, size_t pos = npos) {
if (pos == npos) {
pos = _size - 1;
}
for (int i = _size-1; i > _capcity) {
reserve(len+_size);
}
for (int i = _size+len; i>=pos; i--) {
_str[i+len] = _str[i];
}
while (*p != '\0') {
_str[pos] = *p;
p++;
}
return *this;
}
string& earse(size_t pos,size_t n) {
assert(pos
=0; i--) {
if (ch == _str[i]) {
return i;
}
}
return npos;
}
string substr(size_t pos = 0, size_t n =npos) {
if (n == npos) {
n = _size - pos;
}
char* tmp = new char[n + 1];
strncpy(tmp, _str + pos, n);
tmp[n] = '\0';
string strret(tmp);
delete[] tmp;
return strret;
}
void swap(string& s) {
std::swap(_str,s._str);
std::swap(_size, s._size);
std::swap(_capcity, s._capcity);
}
friend ostream& operator
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)