【c++】string类的使用

目录

一、标准库中的string类

1、简单介绍string类

2、string类的常用接口注意事项

2.1、string类对象的常用构造

2.2、string类对象的容量操作

2.3、string类对象的访问及遍历操作

2.4、string类对象的修改操作

二、string类的模拟实现


一、标准库中的string类

1、简单介绍string类

        (1)string是表示字符串的字符串类;

        (2)string类的接口与常规容器的接口基本相同,在添加了一些专门用来操作string的常规操作;

        (3)string的底层实际是:basic_string模板类的别名,typedef basic_string<char,char_traits,allocator> string;

        (4)不能操作多字节或者变长字符的序列。

2、string类的常用接口注意事项

2.1、string类对象的常用构造

        标准库给出的string类对象常用的构造函数有很多,我们经常用到的主流构造方式有三种:用模板提供的默认构造函数构造空的string类对象、用常量字符串构造string类对象以及用现有的string类对象进行拷贝构造string类对象。

2.2、string类对象的容量操作

        (1)size()与length()方法的底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况先都是用size()。

        (2)clear()只是将string类对象中的有效字符清空,不改变底层空间大小。

        (3)resize(size_t n)与resize(size_t n,char c)都是将字符串中的有效字符个数改变成n个,不同的是当字符个数增多时:resize(n)用0来填充多出来的元素空间,resize(size_t n,char c)是用字符c来填充多出来的元素空间。注意:resize()在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间的总大小保持不变,并不会随着元素个数的减少而缩小容量空间。

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

2.3、string类对象的访问及遍历操作

        string类对象的访问方式有三种:下标访问、迭代器访问、范围for访问。这里主要讨论迭代器访问方式。

        迭代器是一个类,现阶段可以把迭代器当成一个指针来使用(实际上不一定是指针),迭代器是在类的里边定义的,即内部类,使用方式如:string::iterator。string类中与迭代器搭配使用的成员函数包括begin()、end()、rbegin()、rend()。

2.4、string类对象的修改操作

        string类提供了很多字符串修改接口,需要说的是:在string尾部追加自字符时,s.push_back(c)/s.append(1,c)/s+='c'三种实现方式几乎一样,一般情况下更多的选用+=操作,+=操作不仅可以连接单个字符,还可以连接字符串;对string操作时,如果能够大概预估到待存储字符串的长度,可以先通过reserve把空间预留好。

二、string类的模拟实现

#pragma once
#include<iostream>
using namespace std;
#include<assert.h>namespace lbj
{class string{friend ostream& operator<<(ostream& _cout, const string& s);friend istream& operator>>(istream& _cin, string& s);typedef char* iterator;public:string(const char* str = ""){_size = strlen(str);_capacity = _size;_str = new char[_capacity + 1];strcpy(_str, str);}string(const string& s) : _str(nullptr), _size(0), _capacity(0){string tmp(s._str);this->swap(tmp);}string& operator=(const string& s){if (this != &s){string temp(s);this->swap(temp);}return *this;}~string(){if (_str){delete[] _str;_str = nullptr;}}//// iteratoriterator begin(){return _str;}iterator end(){return _str + _size;}/// modifyvoid push_back(char c){if (_size == _capacity)reserve(_capacity * 2);_str[_size++] = c;_str[_size] = '\0';}string& operator+=(char c){   push_back(c);return *this;}void append(const char* str){int len = strlen(str);if (_size + len > _capacity){reserve(_size + len);//_capacity = _size + len;}strcpy(_str + _size, str);   //strcpy()会将‘\0’也拷贝过来,所以不需要手动添加'\0'_size += len;}string& operator+=(const char* str){append(str);return *this;}void clear(){_size = 0;_str[_size] = '\0';}void swap(string& s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}const char* C_Str()const{return _str;}/// capacitysize_t size()const{return _size;}size_t capacity()const{return _capacity;}bool empty()const{return _size == 0;}void resize(size_t newSize, char c = '\0'){if (newSize > _size){// 如果newSize大于底层空间大小,则需要重新开辟空间if (newSize > _capacity){reserve(newSize);}memset(_str + _size, c, newSize - _size);}_size = newSize;_str[newSize] = '\0';}void reserve(size_t newCapacity){// 如果新容量大于旧容量,则开辟空间if (newCapacity > _capacity){char* str = new char[newCapacity + 1];strcpy(str, _str);// 释放原来旧空间,然后使用新空间delete[] _str;_str = str;_capacity = newCapacity;}}/// accesschar& operator[](size_t index){assert(index < _size);return _str[index];}const char& operator[](size_t index)const{assert(index < _size);return _str[index];}///relational operatorsbool operator<(const string& s)const{int res = strcmp(_str, s._str);if (res < 0)return true;return false;}bool operator<=(const string& s)const{return !(*this > s);}bool operator>(const string& s)const{int res = strcmp(_str, s._str);if (res > 0)return true;return false;}bool operator>=(const string& s)const{return !(*this < s);}bool operator==(const string& s)const{int res = strcmp(_str, s._str);if (res == 0)return true;return false;}bool operator!=(const string& s)const{return !(*this == s);}// 返回c在string中第一次出现的位置size_t find(char c, size_t pos = 0) const{for (size_t i = pos; i < _size; ++i){if (_str[i] == c)return i;//找到,返回下标}return -1;//未找到}// 返回子串s在string中第一次出现的位置size_t find(const char* s, size_t pos = 0) const{assert(s);assert(pos < _size);const char* src = _str + pos;while (*src){const char* match = s;//如果不匹配,返回子串起始处重新查找const char* cur = src;while (*match && *match == *cur)//结束条件{++match;++cur;}if (*match == '\0')//找到子串{return src - _str;//返回下标}else{++src;}}return -1;//未找到}// 在pos位置上插入字符c/字符串str,并返回该字符的位置string& insert(size_t pos, char c){assert(pos <= _size);if (_size > _capacity){//扩容char* newstr = new char[_capacity * 2 + 1];//开空间strcpy(newstr, _str);delete[] _str;_str = newstr;_capacity *= 2;//Expand(_capacity * 2);}//移数据for (int i = _size; i >= (int)pos; --i){_str[i + 1] = _str[i];}_str[pos] = c;_size++;return *this;}string& insert(size_t pos, const char* str){size_t len = strlen(str);if (_size + len > _capacity)//扩容{//扩容char* newstr = new char[_capacity * 2 + 1];//开空间strcpy(newstr, _str);delete[] _str;_str = newstr;_capacity *= 2;//Expand(_size + len);}//后移数据for (int i = _size; i >= (int)pos; --i){_str[len + i] = _str[i];}//拷贝字符串while (*str != '\0'){_str[pos++] = *str++;}_size += len;return *this;}// 删除pos位置上的元素,并返回该元素的下一个位置string& erase(size_t pos, size_t len){assert(pos < _size);if (pos + len >= _size)//pos位置之后全为0{_str[pos] = '\0';_size = pos;}else{strcpy(_str + pos, _str + pos + len);_size -= len;}return *this;}private:char* _str;size_t _capacity;size_t _size;};//输入流重载istream& operator>>(istream& _cin, string& s){//预分配100个空间char* str = (char*)malloc(sizeof(char) * 100);char* buf = str;int i = 1;//预处理:跳过流里面的所有空格和回车while ((*buf = getchar()) == ' ' || (*buf == '\n'));for (; ; ++i){if (*buf == '\n') //回车跳出{*buf = '\0';break;}else if (*buf == ' ') //空格跳出{*buf = '\0';break;}else if (i % 100 == 0) //空间不足{i += 100; //追加100个空间str = (char*)realloc(str, i);}else  //每次getchar()一个值{buf = (str + i);//为了避免realloc返回首地址改变,不使用++buf,而是用str加上偏移.//每次读取一个字符*buf = getchar();}}//输入完成,更新ss._str = str;s._capacity = s._size = i;return _cin;}//输出流重载ostream& operator<<(ostream& _cout, const string& s){for (size_t i = 0; i < s.size(); ++i){_cout << s[i];}return _cout;}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/395621.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

拜托了

by Buddy Reno由Buddy Reno Git Please &#xff1a;如何在不做蠢事的情况下强行推动 (Git Please: how to force push without being a jerk) As the size of a dev team grows, so does the likelihood of someone doing a force push and overwriting someone else’s code…

性能测试类型

1.验收性能测试 验收性能测试&#xff08;Acceptance Performance Testing&#xff09;方法通过模拟生产运行的业务压力量和使用场景组合&#xff0c;测试系统的性能是否满足生产性的要求。通俗的说&#xff1a;在特定的运行条件下验证系统的能力状况。 &#xff08;1&#xff…

Java - 对象(object) 具体解释

对象(object) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/24059545 对象(object)的实例能够是 物理对象(如 人, 车等实物) 或 逻辑对象(如 运动, 健康等); 对象是将状态(数据) 和行为(功能) 组合在一起的软件模块. 类是描写叙述一组相似对象共同…

kkt条件的matlab仿真,请教关于SVM中KKT条件的推导

KKT条件第一项是说最优点必须满足所有等式及不等式限制条件&#xff0c;也就是说最优点必须是一个可行解&#xff0c;这一点自然是毋庸置疑的。第二项表明在最优点 x*&#xff0c; ∇f 必須是 ∇hj 和 ∇gk 的线性組合&#xff0c;和都叫作拉格朗日乘子。所不同的是不等式限制条…

公共wifi做家用_如何在公共网络上获得免费的wifi

公共wifi做家用by Kyle McDonald凯尔麦克唐纳(Kyle McDonald) 如何在公共网络上获得免费的wifi (How to get free wifi on public networks) This short tutorial describes a few methods for gaining access to the internet, a basic human right, from public wireless ne…

python学习之旅

一、入门 1.Python 面向对象编程 2.jquery入门 3.HTMLCSS基础入门 4.Javascript初步 5.Python语言编程基础 二、初级阶段 1.Git 与 GitHub 2.Python 爬虫基础 3.django进阶 4.django项目部署 5.ajax入门 6.django基础 7.Mysql基础 三、中级阶段 1.Linux基础 2.Python :socket a…

c/c++ 重载运算符 函数调用运算符

重载运算符 函数调用运算符 把一个类的对象a&#xff0c;当成函数来使用&#xff0c;比如a()&#xff0c;所以需要重载operator()方法。重载了函数调用运算符的类的对象&#xff0c;就是函数对象了。 还有什么是函数对象呢&#xff1f;&#xff1f;&#xff1f; lambda是函数对…

matlab 万能,matlab 万能实用的线性曲线拟合方法

在科学计算和工程应用中&#xff0c;经常会遇到需要拟合一系列的离散数据&#xff0c;最近找了很多相关的文章方法&#xff0c;在这里进行总结一下其中最完整、几乎能解决所有离散参数线性拟合的方法第一步&#xff1a;得到散点数据根据你的实际问题得到一系列的散点例如&#…

socket websocket

1.websocket客户端 websocket允许通过JavaScript建立与远程服务器的连接&#xff0c;从而实现客户端与服务器间双向的通信。在websocket中有两个方法&#xff1a;      1、send() 向远程服务器发送数据    2、close() 关闭该websocket链接  websocket同时还定义了几…

javascript原型_JavaScript的原型:古怪,但这是它的工作原理

javascript原型by Pranav Jindal通过普拉纳夫金达尔 JavaScript的原型&#xff1a;古怪&#xff0c;但这是它的工作原理 (Prototype in JavaScript: it’s quirky, but here’s how it works) The following four lines are enough to confuse most JavaScript developers:以下…

mysql函数之SUBSTRING_INDEX(str,/,-1)

SUBSTRING_INDEX的用法&#xff1a; •SUBSTRING_INDEX(str,delim,count) 在定界符 delim 以及count 出现前&#xff0c;从字符串str返回自字符串。若count为正值,则返回最终定界符(从左边开始) 若为-1则是从后往前截取 SELECT substring_index(Hn_P00001, P, -1) -- 结果是…

mysql8.0主从配置,MySQL 8.0主从服务器(Master-Slave)配置

一、介绍MySQL 主从复制的方式有多种&#xff0c;本文主要演示基于基于日志(binlog)的主从复制方式。MySQL 主从复制(也称 A/B 复制) 的原理&#xff1a;Master将数据改变记录到二进制日志(binary log)中&#xff0c;也就是配置文件log-bin指定的文件&#xff0c; 这些记录叫做…

第十二章 Shell脚本编写及常见面试题(三)

本章目录&#xff1a;12.21 FTP下载文件#!/bin/bash if [ $# -ne 1 ]; thenecho "Usage: $0 filename" fi dir$(dirname $1) file$(basename $1) ftp -n -v << EOF # -n 自动登录 open 192.168.1.10 user admin adminpass binary # 设置ftp传输模式为二进制…

亚马逊面试有几轮_经过几个月的Google面试准备,我被亚马逊录用

亚马逊面试有几轮by Googley as Heck由Googley饰演Heck 经过几个月的Google面试准备&#xff0c;我被亚马逊录用 (After months of preparing for the Google interview, I got hired by Amazon) As you may know, the last 11 months have been very difficult for me. As a …

省选前的考试记录

日拱一卒功不唐捐 什么沙雕玩意儿 2018.12.24 T1 如果对 \(A\) 数组求出来高度递减的单调栈的话&#xff0c;会发现只有单调栈里的元素是有用的。因为如果有 \(A[i]<A[j] \And i<j\)&#xff0c;那电梯就可以在带 \(j\) 上楼的时候顺便把 \(i\) 带上并不会影响结果。所以…

软件工程课设-----日程管理系统

这学期进行了软件工程课设&#xff0c;题目是&#xff1a;日程管理系统&#xff08;JavaWeb&#xff09;&#xff0c;为期3周。这三周只有前两天是企业老师讲解是企业老师讲解相关的基础知识(老师讲的水平实在是不可恭维。。。。。。)。 多的不多说。直接进行对相关项目的介绍。…

matlab中的神经网络训练,MATLAB中的神经网络训练

我试图向前馈送反向传播&#xff0c;但是在网络训练之后&#xff0c;当模拟和打印模拟输出时&#xff0c;我看不到任何靠近目标的值&#xff0c;但它只是一个数字。代码如下。什么是错&#xff0c;什么是问题&#xff1f;前馈反向传播&#xff1a;>> load(E:/Inputdata.t…

Spring For All 顶级Spring综合社区服务平台

Spring For All 玩最纯粹的技术&#xff01;做最专业的 Spring 民间组织~ 欢迎加入&#xff1a;http://spring4all.com/ image.png

chromium 桌面_如何使用Chromium和PyInstaller将Web应用程序转换为桌面应用程序

chromium 桌面Packaging and distributing your app sounds simple in principle. It’s just software. But in practice, it’s quite challenging.打包和分发应用程序在原理上听起来很简单。 这只是软件。 但是在实践中&#xff0c;这非常具有挑战性。 I’ve been working …