欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 名人名企 > C++—>STL中string篇

C++—>STL中string篇

2024/10/24 12:33:06 来源:https://blog.csdn.net/2301_78704584/article/details/140996768  浏览:    关键词:C++—>STL中string篇

在这里插入图片描述

文章目录

  • 前言
    • 1、标准库中string介绍
    • 2、string的构造函数使用
    • 3、string访问方式
    • 4、string常用的接口描述
      • 4.1 string类对象常见的构造
      • 4.2string类对象的容量操作
    • 5、string类的模拟实现

前言

我们在C语言中学习了字符串(用双引号引起的以’/0’结尾的一串字符),并提供了字符串库函数的使用,但为了更好的使用,C++中分封装了字符串的类——string,提高效率。接下来我们看看string的相关知识。🚗

1、标准库中string介绍

string标准库


2、string的构造函数使用

主要是默认的无参构造函数、拷贝构造函数、从原来的string对象拷贝新对象等。
在这里插入图片描述
在这里插入图片描述


3、string访问方式

下面是下标+[ ]遍历、迭代器遍历、范围for遍历:

int main()
{string s1("Hello Word!");//下标[]访问:cout << s1[0] << endl;//下标+[]遍历for (int i = 0; i < s1.size(); i++){cout << s1[i] << " ";}cout << endl;//迭代器访问string::iterator it = s1.begin();while (it != s1.end()){cout << *it << " ";++it;}cout << endl;//范围for访问,auto自动推导s1的类型,自动迭代、自动判断结束for (auto ch : s1){cout << ch << " ";}cout << endl;return 0;
}

4、string常用的接口描述

4.1 string类对象常见的构造

函数名作用
string()默认构造函数,构造空的string类——空字符
string(const char* s)用已经有的string对象来构造string新对象
string(const string &s)拷贝构造函数
string(size_t n,char c)构造一个包含n个字符c
int main()
{string s1;string s2("STL Hello!");string s3(s2);string s4(5, 'M');cout << s1 << endl;cout << s2 << endl;cout << s3 << endl;cout << s4 << endl;return 0;
}

4.2string类对象的容量操作

函数名称功能说明
size返回字符串有效字符长度
length返回字符串有效字符长度
capacity返回空间总大小
empty检测字符串释放为空串,是返回true,否则返回false
clear清空有效字符
reserve为字符串预留空间**
resize将有效字符的个数改成n个,多出的空间用字符c填充

注意:
①size()和length()方法实现的原理完全相同。
clear操作后,只是把数据清空为0,空间大小不会改变;
③resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个;

区别在于当字符个数增多时:
resize(n)用0来填充多出的元素空间;
resize(size_t n, charc)用字符c来填充多出的元素空间。
注意:resize在改变元素个数时,如果是将元素个数增多,
可能会改变底层容量的大小,如果是将元素个数减少,
底层空间总大小不变。

④ reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

大小空间的使用:

int main()
{//size()和length()是一样的实现原理string str1("hello C++ programmer");cout << "str1的size:" << str1.size() << "\n";cout << "str1的length:" << str1.length() << "\n";cout << "str1的容量capacity:" << str1.capacity() << "\n";cout << "使用clear清空后,不会改变容量大小:"<<endl;str1.clear();cout << "str1的容量capacity:" << str1.capacity() << "\n";return 0;
}

在这里插入图片描述

5、string类的模拟实现

String.h短小或频繁调用的函数就直接写在类里面

#define _CRT_SECURE_NO_WARNINGS 1#pragma once
#include<iostream>
#include<string>
#include<cassert>
using namespace std;namespace zc
{class String{friend ostream& operator<<(ostream& _cout, const zc::String& s);friend istream& operator>>(istream& _cin, zc::String& s);public:typedef char* iterator;public:无参构造函数,初始化列表实现//String()//	:_str(new char[1] {'\0'})//	, _size(0)//	,_capacity(0)//{}带参构造函数//String(const char* str)//{//	_size = strlen(str);//	_capacity = _size;//	_str = new char[_capacity + 1];//因为不包含\0,因此多开一个空间//	strcpy(_str,str);//}//直接合并写为全缺省构造函数String(const char* str=""){_size = strlen(str);_capacity = _size;_str = new char[_capacity + 1];strcpy(_str,str);}//拷贝构造函数String(const String& str){_str = new char[str._capacity + 1];strcpy(_str,str._str);_size = str._size;_capacity = str._capacity;}String& operator=(const String& str){delete[] _str;_str = new char[str._capacity+1];strcpy(_str, str._str);_size = str._size;_capacity = str._capacity;return *this;}//析构函数~String(){delete[] _str;_str = nullptr;_size = _capacity = 0;}const char* c_str() const{return _str;}/*^^^^^^^^^^^^^^^^^^^^^^^^*///capacity的相关函数size_t size()const{return _size;}size_t capacity()const{return _capacity;}bool empty()const{return _size == 0;}void reserve(size_t n);/*^^^^^^^^^^^^^^^^^^^^^^^^*///access(访问相关函数)//可修改的[]访问char& operator[](size_t index){assert(index>=0);return _str[index];}//只读不写const char& operator[](size_t index)const{assert(index>=0);return _str[index];}/*^^^^^^^^^^^^^^^^^^^^^^^^*///iterator迭代器相关函数iterator begin(){return _str;}iterator end(){return _str + _size;}/*^^^^^^^^^^^^^^^^^^^^^^^^*///modify相关函数void push_back(char ch);String& operator+=(char ch);void append(const char* str);String& operator+=(const char* str);void clear();/*^^^^^^^^^^^^^^^^^^^^^^^^*///relational operatorsbool operator<(const String& s){return strcmp(this->_str, s.c_str())<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);}bool operator==(const String& s){return strcmp(this->_str,s.c_str())==0;}bool operator!=(const String& s){return !(*this == s);}// 返回c在string中第一次出现的位置size_t find(char c, size_t pos = 0) const;// 返回子串s在string中第一次出现的位置size_t find(const char* s, size_t pos = 0) const;void insert(size_t pos, char ch);void insert(size_t pos, const char* str);void erase(size_t pos,size_t len=npos);String substr(size_t pos, size_t len = npos);private:char* _str;size_t _size;size_t _capacity;const static size_t npos = -1;};ostream& operator<<(ostream& _cout, const zc::String& s);istream& operator>>(istream& _cin, zc::String& s);void Test_string();
}

String.cpp

#include "String.h"namespace zc
{void String::reserve(size_t n){if (n > _capacity){char* tmp = new char[n+1];//多开一个strcpy(tmp,_str);//释放就空间delete[] _str;_str = tmp;_capacity = n;}}void String::push_back(char ch){//扩容机制if (_size == _capacity){reserve(_capacity==0?4:_capacity*2);}_str[_size] = ch;++_size;_str[_size] = '\0';}String& String::operator+=(char ch){push_back(ch);return *this;}void String::append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){reserve(_size + len > _capacity * 2 ? _size + len : _capacity * 2);}strcpy(_str+_size,str);_size += len;}String& String::operator+=(const char* str){append(str);return *this;}void String::clear(){_str[0] = '\0';_size = 0;}size_t String::find(char c, size_t pos) const{assert(pos<=_size&&pos>=0);for (size_t i = pos; i < _size; i++){if (_str[i] == c){return i;}}return pos;}size_t String::find(const char* s, size_t pos) const{assert(pos<_size);const char* ptr = strstr(_str + pos, s);if (ptr == nullptr){return npos;}else{return ptr - _str;}}void String::insert(size_t pos, char ch){//检查位置是否合法assert(pos>=0&&pos<=_size);//空间if (_size == _capacity){reserve(_capacity==0?4:_capacity*2);}插入//int end = _size;//while (end >= (int)pos)//存在类型自动转换,因为pos是size_t无符号,因此需要强转//{//	//移动//	_str[end + 1] = _str[end];//	--end;//}size_t end = _size + 1;while (end > pos){_str[end] = _str[end - 1];--end;}_str[pos] = ch;++_size;}void String::insert(size_t pos,const char* str){//检查位置是否合法assert(pos >= 0 && pos <= _size);//空间size_t len = strlen(str);if (_size+len >  _capacity){reserve(_size+len>2*_capacity?_size+len:2*_capacity);}size_t end = _size + len;while (end>pos+len-1){_str[end] = _str[end - len];--end;}for (size_t i = 0; i < len; i++){_str[pos + i] = str[i];}_size += len;}void String::erase(size_t pos, size_t len){assert(pos<=_size&&pos>=0);if (len >= _size - pos){//所要删除数据的长度大于后面剩余数据的长度,就全部删除_str[pos] = '\0';_size = pos;}else{//按所给的长度删除,需要挪动数据for (size_t i = pos + len; i <= _size; i++){_str[i - len] = _str[i];}//改变长度_size -= len;}}String String::substr(size_t pos, size_t len){assert(pos <= _size && pos >= 0);//len大于剩余长度就更新if (len > _size - pos){len = _size - pos;}String sub;reserve(len);for (int i = 0; i < len; i++){sub += _str[pos + i];}return sub;}ostream& operator<<(ostream& _cout, const zc::String& s){for (size_t i = 0; i < s.size(); ++i){_cout << s[i];}return _cout;}istream& operator>>(istream& _cin, zc::String& s){s.clear();/*	char ch=_cin.get();while (ch !=' ' && ch != '\n'){s += ch;ch = _cin.get();}*/const int N = 256;char buff[N];int i = 0;char ch;ch=_cin.get();while (ch != ' ' && ch != '\n'){buff[i++] = ch;if (i == N - 1){buff[i] = '\0';s += buff;i = 0;}ch = _cin.get();}if (i > 0){buff[i] = '\0';s += buff;}return _cin;}
}

test.cpp测试源文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"String.h"namespace zc
{void zc::Test_string(){String s1;String s2("hello C++ programmer!");cout << s1.c_str() << endl;cout << s2.c_str() << endl;cout << "s1大小:" << s1.size() << endl;cout << "s2大小:" << s2.size() << endl;cout << "s1空间:" << s1.capacity() << endl;cout << "s2空间:" << s2.capacity() << endl;cout << "s1是否为空:" << s1.empty() << endl;cout << "s2是否为空:" << s2.empty() << endl;cout << endl;cout << "s2清除后:" << endl;s2.clear();cout << "s2大小:" << s2.size() << endl;cout << "s2空间:" << s2.capacity() << endl;cout << "s2是否为空:" << s2.empty() << endl;String s3("hello word");for (auto ch : s3){cout << ch << " ";}cout << endl;/*	String::iterator it = s3.begin();while (it != s3.end()){cout << *it << " ";++it;}cout << endl;*/s3[0] = 'H';s3[6] = 'W';for (int i = 0; i < s3.size(); i++){cout << s3[i] << " ";}cout << endl;s3.push_back('C');cout << s3.c_str() << endl;s3 += 'F';cout << s3.c_str() << endl;s3.append("string");cout << s3.c_str() << " ";cout << endl;s3 += "zhou";cout << s3.c_str() << " ";cout << endl;String s4("word");cout << s4.c_str() << endl;//s4.insert(0, 'm');s4.insert(4, '!');cout << s4.c_str() << endl;s4.insert(0, "hello ");cout << s4.c_str() << endl;s4.erase(6,3);cout << s4.c_str() << endl;s4.erase(4);cout << s4.c_str() << endl;String s5("C++ programmer!");cout << s5.c_str() << endl;size_t pos=s5.find('p');String str = s5.substr(pos);cout << str.c_str() << endl;String s6("C++");cout << s6.c_str() << endl;s5 = s6;cout << s5.c_str() << endl;String s7("C++");cout << (s6 == s7) << endl;cout << s6 << endl;String s8;cin >> s8;cout << s8 << endl;}
}int main()
{zc::Test_string();return 0;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com