标准库中的string类
- string是表示字符串的字符串类
- 该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
- string在底层实际是:basic_string模板类的别名,typedef basic_string<char,char_traits,allcator>string;
- 不能操作多字节或者变长字符的序列。
在使用string类时,必须包含#include头文件以及using namespace std命名空间;
string类对象的容量操作
函数名称 | 功能 |
---|---|
size | 返回字符串有效长度 |
length | 返回字符串有效长度长度 |
capacity | f返回空间总大小 |
empty | 判空 |
clear | 清空有效字符串 |
reserve | 为字符串预留空间 |
resize | 将有效字符的个数改为n个,多出的空间用c填充 |
- size()与length()方法底层实现原理完全相同,一般情况下基本都是用size()。
- clear()只是将string中有效字符清空,不改变底层空间大小。
- resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字 符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_tn, char c)用字符c来填充多出的 元素空间。
注意:
resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。- reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于 string的底层空间总大小时,reserver不会改变容量大小。
string的模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<string>
#include<assert.h>
using namespace std;
#if 0
namespace lei{
class string
{
public:
string(const char* str = ""){
if (nullptr == str){
assert(str);
return;
}
_str = new char[strlen(str) + 1];
strcpy(_str, str);
}
string(const string& s) :
_str(new char[strlen(s._str) + 1]){
strcpy(_str, s._str);
}
string& operator=(const string& s){
if (this != &s){
delete[]_str;
_str = new char[strlen(s._str) + 1];
strcpy(_str, s._str);
}
return *this;
}
~string(){
delete[]_str;
_str = nullptr;
}
private:
char* _str;
};
}
class string
{
public:
string(const char* str = "");
string(const string &s);
string& operator=(const string &s);
~string();
private:
char *_str;
};
#endif
namespace feng{
class string{
friend ostream& operator<<(ostream& _cout, const feng::string& s);
friend istream& operator>>(istream& _cin, feng::string& s);
public:
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;
}
}
iterator
iterator begin(){
return _str;
}
iterator end(){
return _str + _size;
}
///modify
void 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);
string& operator+=(const char* str);
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;
}
///capacity
size_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){
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;
}
}
///access
char& operator[](size_t index){
assert(index < _size);
return _str[index];
}
const char& operator[](size_t index)const{
assert(index < _size);
return _str[index];
}
///relation operators
bool operator<(const string& s){
int res = strcmp(_str, s._str);
if (res<0)
return true;
}
bool operator<=(const string& s){
return !(*this>s);
}
bool operator>(const string& s){
int res = strcmp(_str, s._str);
if (res > 0)
return true;
return false;
}
bool operator>=(const string& s){
return !(*this < s);
}
bool operator==(const string& s){
int res = strcmp(_str, s._str);
if (res == 0)
return true;
return false;
}
bool operator!=(const string& s){
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;
}
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;
}
for (inr 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){
_str[pos] = '\0';
_size = pos;
}
else{
strcpy(_str + pos; _str + pos + len);
_size -= len;
}
return *this;
}
private:
friend ostream& operator<<(ostream& _cout, const feng::string& s);
friend istream& operator>>(istream& _cin, feng::string& s);
char* _str;
size_t _capacity;
size_t _size;
};
}
istream& feng::operator>>(istream& _cin, feng::string& s){
char* str = (char*)malloc(sizeof(char)* 100);
char* buf = str;
int i = 0;
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;
str = (char*)realloc(str, i);
}
else{
*buf = getchar();
}
}
s._str = str;
s._capacity = s._size = i;
return _cin;
}
ostream& feng::operator<<(ostream& _cout, const feng::string& s){
for (size_t i = 0; i < s.size(); ++i){
cout << s[i];
}
return _cout;
}