【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.pswp.cn/news/395621.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/395621.shtml
英文地址,請注明出處:http://en.pswp.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 …