从C++开始的编程生活(11)——string类基本语法和string类的基本实现
前言
本系列文章承接C语言的学习,需要有C语言的基础才能学会哦~
第11篇主要讲的是有关于C++的string类基本语法和string类的基本实现。
C++才起步,都很简单!!
string
string的接口很多,这里只展示常见常用的函数。
基本语法(续上篇)
resize( )
重新设置大小,可能会删除数据。
string s1 = “11111111111111111111”;s1.resize(15);
s1.resize(30, 'x');
有三种情况:
①resize的大小n < size的大小,缩短,删除第n开始的字符。
②capacity > resize的大小n > size的大小,结尾插入字符,直到字符数等于n,默认插入‘ /0 ‘。
③resize的大小n > capacity,会扩容。
assign( )
赋值字符串,类似operator=,但是比operator=复杂。当前有值会被覆盖掉。
s1.assign("hello");
s1.assign("hello", 2);//从2位置开始赋值
s1.assign("hello", 2, 2);//从2位置开始,取2个字符赋值
erase( )
删除字符串
s1.erase(1);//从1位置开始删除字符,全部删除完
s1.erase(1, 2);////从1位置开始删除2个字符
s1.erase(s1.begin(),s1.begin() + 2);//删除区间内字符
第一个参数是索引,超出范围会抛异常。而且是在原本的字符串上修改,不会生成新的字符串。
replace( )
替换字符串
string str = "Hello, World!";// 1. 替换从位置6开始的5个字符(即" World")为" C++"
str.replace(6, 5, " C++");// 输出: Hello, C++!// 2. 替换从位置0开始的5个字符(即"Hello")为"Hi"
str.replace(0, 5, "Hi");// 输出: Hi, C++!// 3. 用另一个字符串的子串替换
string source = "Programming";
str.replace(4, 3, source, 0, 4); // 从位置4开始替换3个字符,用source的前4个字符"Prog"
// 输出: Hi, Prog!// 4. 用空字符串替换
str.replace(3, 1, ""); // 从位置3开始删除1个字符(逗号)
// 输出: Hi Prog!// 5. 用重复的字符替换
str.replace(0, 2, 3, 'A'); // 从位置0开始替换2个字符,用3个'A'
// 输出: AAA Prog!
共五种替换方法,但是该函数效率较低,不适合大量使用。如果替换的字符数大于被替换的字符,替换位置后的字符会往后挪;反之会往前挪。
find( )
查找字符位置
size_t i = s1.find(' ');//默认0开始查找
size_t j = s1.find(' ', i + 1);//从i + 1位置找
可以和replace( )搭配使用,快速找到替换位置。
pop_back( )
尾删
用法类似尾插,不再展示。
c_str( )
获得字符串的const指针,主要是为了和C语言保持兼容,因为string是类,不兼容C语言,不能用C语言进行字符串操作。
const cahr* p1 = s1.c_str();
rfind( )
倒着查找,和find除了方向不同,功能一样。取文件后缀可以使用这个函数。
size_t i = s1.rfind(' ');//默认最后位置开始查找
size_t j = s1.rfind(' ', i + 1);//从i + 1位置开始往前找
substr( )
取当前string的子串
string sub = s1.substr(2, 3);//从2位置取3个字符的子串
string sub = s1.substr(2);//从2位置开始取全部字符的子串
find_first_of( )
找一个包含于给定的字符串中的字符,并返回位置。
size_t = found = s1.find_first_of("aeiou");//默认从0位置开始找
size_t = found = s1.find_first_of("aeiou", 5);//从5位置开始找
find_last_of( )
同find_first_of( ),但是反过来找。
find_first_not_of( )和find_last_not_of( )
分别是上面两个函数的反函数,也就是找不包含于给定字符串的字符
substr( )
提取字符串
string str = s1.substr(0);//从0开始,默认提取整个字符串
string str = s1.substr(0, 5);//从0开始,提取5个字符
getline( )
提取字符串。
string str;
getline(cin, str);//默认遇到换行停止提取
getline(cin, str, '#');//遇到‘#’停止提取
如果只用cin输入,遇到空格的时候,cin会把空格当成输入间隔,会停止输入。
而且可以指定提取结束字符。
to_string( )
转字符串
//double类型转为了string
string str = to_string(123.456);
还有类似的函数:stoi( ),stoul( )等,了解即可。
string类的模拟实现
目的是为了更好的了解string类成员函数的底层实现。
string.cpp
#include"string.h"namespace bit
{string::string(const char* str):_size(0){_capacity = _size;_str = new char[_size + 1];strcpy(_str, str);}string::~string(){delete[] _str;_str = nullptr;_size = 0;_capacity = 0;}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++;}void string::append(const char* str){size_t len = strlen(str);if (_size + len > _capacity){size_t newCapacity = 2 * _capacity;if (newCapacity < _size + len)newCapacity = _size + len;reserve(newCapacity);}}string& string::operator+=(char ch){push_back(ch);}string& string::operator+=(const char* str){append(str);}void string::insert(size_t pos, char ch){assert(pos <= _size);if (_size == _capacity){reserve(_capacity == 0 ? 4 : 2 * _capacity);}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 < _size);size_t len = strlen(str);if (_size + len > _capacity){size_t newCapacity = 2 * _capacity;if (newCapacity < _size + len)newCapacity = _size + len;reserve(newCapacity);}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] = str[i];}_size += len;}void string::earse(size_t pos, size_t len){if (len >= _size - pos){_str[pos] = '\0';_size = pos;}else{size_t end = pos + len;while (end <= _size){_str[end - len] = _str[end];++end;}_size -= len;}}
}
string.h
#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<assert.h>
using namespace std;
namespace bit
{class string{public:using iterator = char*;using const_iterator = const char*;//拷贝string(const char* str = "");//析构~string();//接口void reserve(size_t n);void push_back(char ch);void append(const char* str);string& operator+=(char ch);string& operator+=(const char* str);void insert(size_t pos, char ch);void insert(size_t pos, const char* str);void earse(size_t pos, size_t len);const char* c_str() const{return _str;}char& operator[](size_t i){assert(i < _size);return _str[i];}const char& operator[](size_t i)const{assert(i < _size);return _str[i];}size_t size() const{return _size;}iterator begin(){return _str;}iterator end(){return _str + _size;}const_iterator begin() const{return _str;}const_iterator end() const{return _str + _size;}private:size_t _size;size_t _capacity;char* _str;public://只有整型可以,是一种特殊处理,可以不用声明与定义分离static const size_t npos = -1;};}
❤~~本文完结!!感谢观看!!接下来更精彩!!欢迎来我博客做客~~❤