当前位置:首页 » 《随便一记》 » 正文

【C++】string 类

3 人参与  2024年03月05日 18:26  分类 : 《随便一记》  评论

点击全文阅读


1. 标准库中的string类

注意:

1. string是表示字符串的字符串类

2. 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。 比特就业课

3. string在底层实际是:basic_string模板类的别名,typedef basic_string string;

4. 不能操作多字节或者变长字符的序列。 在使用string类时,必须包含#include头文件(#include<string>)以及using namespace std;

a. string类对象的常见构造

代码举例1

#include <iostream>#include<string>using namespace std;int main(){string t1; // 相当于类对象的实例化}

代码举例2

#include <iostream>#include<string>using namespace std;int main(){string t1("hello world"); // 调用构造函数cout << t1 << endl;string t2 = "hello world"; //隐式类型转换(构造函数 + 拷贝构造 + 优化 -> 构造函数)cout << t2 << endl;}

代码举例3

#include <iostream>#include<string>using namespace std;int main(){string t1(10, 'a');  // 拷贝 10 个 acout <<  t1 << endl;}

运行结果:

代码举例4

#include <iostream>#include<string>using namespace std;int main(){string t1("hello");string t2(t1); // 拷贝构造cout << t2 << endl;}

b. string类对象的容量操作

size (返回字符串有效字符长度,没有 '\0 ')

代码举例1

#include <iostream>#include<string>using namespace std;int main(){string t1 = "hello";cout << t1.size() << endl;}

运行结果:

capacity (返回字符串的总空间大小)

代码举例2

#include <iostream>#include<string>using namespace std;int main(){string t1 = "hello";cout << t1.capacity() << endl;}

运行结果:

分析:

string 类里面的成员变量有两个可以存储空间,一个是数组,另一个是动态开辟的空间,当数组空间不足时,才会用动态开辟

reserve(扩大字符串容量,字符有效长度不变:即 size 不变)

代码举例3

#include <iostream>using namespace std;int main(){string t1 = "hello";cout << "有效长度:" << t1.size() << " 总容量:" << t1.capacity() << endl;t1.reserve(100);cout << "有效长度:" << t1.size() << " 总容量:" << t1.capacity() << endl;}

运行结果:

分析:

有些编译器在分配空间的时候,可能会对于开辟所需的空间再给大一点

resize (将有效字符的个数该成n个,多出的空间用字符c填充)

代码举例4

#include <iostream>using namespace std;int main(){string t1 = "hello";cout << "有效长度:" << t1.size() << " 总容量:" << t1.capacity() << endl;t1.resize(100);cout << "有效长度:" << t1.size() << " 总容量:" << t1.capacity() << endl;t1.resize(10); //可以缩小有效长度,但总容量不会随意变动cout << "有效长度:" << t1.size() << " 总容量:" << t1.capacity() << endl;t1.resize(20, '*'); //对于的空间可以初始化任意字符cout << t1 << endl;}

运行结果:

c. string类对象的访问及遍历操作

operator[] (返回pos位置的字符,和 C 语言的用法一样,const string类对象调用)begin + end (begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器)

代码举例1

#include <iostream>using namespace std;int main(){string t1 = "hello bit";string::iterator it = t1.begin();// it 相当于拿到 首元素的地址了while (it != t1.end()){cout << *it << endl;it++;}}

运行结果:

分析:

rbegin + rend (rbegin获取最后一个字符的迭代器 + rend获取第一个字符前一个位置的迭代器)

代码举例2

#include <iostream>using namespace std;int main(){string t1 = "hello bit";string::reverse_iterator rit = t1.rbegin();// it 相当于拿到 首元素的地址了while (rit != t1.rend()){cout << *rit << endl;rit++;}}

运行结果:

分析:

范围for

代码举例3

#include <iostream>using namespace std;int main(){string t1 = "hello bit";for (auto i : t1){cout << i;}cout << endl;for (int i = 0; i < t1.size(); i++){cout << t1[i];}}

运行结果:

d. string类对象的修改操作

push_back (在字符串后面增加一个字符)

代码举例1

#include <iostream>using namespace std;int main(){string t1 = "hello";t1.push_back('a');t1.push_back('a');t1.push_back('a');cout << t1 << endl;}

运行结果:

append (在字符串后面再增加一个字符串)

代码举例2

#include <iostream>using namespace std;int main(){string t1 = "hello";t1.append("abcd");cout << t1 << endl;}

运行结果:

operator+= (在字符串后面加一个字符或者一个字符串)

代码举例3

#include <iostream>using namespace std;int main(){string t1 = "hello";t1 += "aabc";t1 += '*';cout << t1 << endl;}

运行结果:

c_str (返回存储的字符串)

代码举例4

#include <iostream>using namespace std;int main(){string t1 = "hello";t1 += '\0';t1 += 'a';cout << t1 << endl;cout << t1.c_str();}

运行结果:

分析:

c_str() 是直接返回字符串 ,所以遇到 '\0' 就终止了

的完成是根据_size去遍历每个字符串

find + npos (从字符串pos位置开始往后找字符c,返回第一次遇到的该字符在字符串中的位置)

代码举例5

#include <iostream>using namespace std;int main(){string t1 = "hello";cout << t1.find('o',2) << endl;// 从下标为 2 的位置去找字符 'o'cout << t1.find("lo") << endl;// 默认从下标 0 的位置去找字符串}

注意:

如果找不到,返回 npos ( size_t npos = -1)默认 pos 从 0 下标开始 rfind(从字符串pos位置开始往前找字符c,返回第一次遇到该字符在字符串中的位置)

代码举例6

#include <iostream>using namespace std;int main(){string t1 = "hello";cout << t1.rfind('l') << endl;}

运行结果:

注意:

如果找不到,返回 npos ( size_t npos = -1)默认 pos 从 字符串中的最后一个字符(不是 '\0' ) 下标开始

e. string类非成员函数

operator>> (输入运算符重载)operator<< (输出运算符重载)getline (获取一行字符串)

代码举例

#include <iostream>#include <string>using namespace std;int main(){string t1;getline(cin, t1);cout << t1 << endl;return 0;}

注意:

getline 遇到空格不会结束

cin 遇到空格会结束

 2. string 类的模拟

namespace lhy{class string{public:typedef char* iterator;typedef const char* const_iterater;iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterater begin() const{return _str;}const_iterater end() const{return _str + _size;}string(const char* str = ""):_size(strlen(str)){_capacity = _size == 0 ? 3 : _size;_str = new char[_capacity + 1];strcpy(_str, str);}string(const string& t):_size(strlen(t._str)){_capacity = t._size;_str = new char[_capacity + 1];strcpy(_str, t._str);}string(int n, char ch):_size(n){_capacity = _size;_str = new char[_capacity + 1];for (int i = 0; i < n; i++){_str[i] = ch;}_str[_capacity] = '\0';}string& operator=(const string& t){_size = t._size;_capacity = t._capacity;char* tmp = new char[_capacity + 1];strcpy(tmp, t._str);delete[] _str;_str = tmp;return *this;}char& operator[](int pos){assert(pos < _size);return _str[pos];}const char& operator[](int pos) const {assert(pos < _size);return _str[pos];}size_t size() const{return _size;}const char* c_str() const{return _str;}bool operator>(const string& t) const{if (strcmp(_str, t._str) > 0){return true;}return false;}bool operator==(const string& t) const{if (strcmp(_str, t._str) == 0){return true;}return false;}bool operator<(const string& t) const{if (strcmp(_str, t._str) < 0){return true;}return false;}bool operator<=(const string& t) const{return *this < t || *this == t;}bool operator>=(const string& t) const{return *this > t || *this == t;}bool operator!=(const string& t) const{return !(*this == t);}void push_back(const char ch){if (_size + 1 > _capacity){reserve(_size * 2);}_size++;_str[_size - 1] = ch;_str[_size] = '\0';}void append(const char* str){int len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}strcpy(_str + _size, str);_size += len;}void reserve(size_t n){if (n > _size){char* tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}}void resize(size_t size,char ch = '\0'){if (size > _size){reserve(size);int x = size - _size;while (x--){*this += ch;}_size = size;}else{_size = size;_str[_size] = '\0';}}void insert(size_t pos,const char ch){assert(pos <= _size);if (_size + 1 > _capacity){reserve(_size * 2);}_size++;for (int i = _size; i > pos; i--){_str[i] = _str[i - 1];}_str[pos] = ch;}void insert(size_t pos,const char* str){assert(pos <= _size);int len = strlen(str);if (_size + len > _capacity){reserve(_size + len);}_size += len;for (size_t i = _size; i > pos + len - 1; i--){_str[i] = _str[i - len];}strncpy(_str + pos, str, len);}void erase(size_t pos,size_t n = npos){assert(pos <= _size);if (n == npos || pos + n >= _size ){_str[pos] = '\0';_size = pos;}else{for (int i = pos + n; i <= this->size(); i++){_str[i - n] = _str[i];}_size -= n;}}void swap(string &t){std::swap(_size, t._size);std::swap(_capacity, t._capacity);std::swap(_str, t._str);}size_t find(const char ch, size_t pos = 0){assert(pos < _size);for (size_t i = pos; i < this->size(); i++){if (_str[i] == ch){return i;}}return -1;}size_t find(const char* str, size_t pos = 0){assert(pos < _size);char *tmp = std ::strstr(_str + pos, str);if (tmp == nullptr){return -1;}else{return tmp - _str;}}string& operator+=(const char *str){append(str);return *this;}string& operator+=(const char ch){push_back(ch);return *this;}void clear(){_str[0] = '\0';_size = 0;}~string(){delete[] _str;_str = nullptr;}private:char* _str;size_t _size;size_t _capacity;static size_t npos;};size_t string::npos = -1;ostream& operator<<(ostream& out, const string& t){for (size_t i = 0; i < t.size(); i++){out << t[i];}return out;}istream& operator>> (istream& in,string& t){t.clear();int i = 0;char tmp[128];char ch = in.get();while (ch != ' ' && ch != '\n'){tmp[i++] = ch;if (i == 126){tmp[i + 1] = '\0';t += tmp;i = 0;}ch = in.get();}if (i != 0){tmp[i] = '\0';t += tmp;}return cin;}}


点击全文阅读


本文链接:http://zhangshiyu.com/post/74315.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1