C++ STL-string
目录
C++ STL-string
●1.string类对象的常见构造
●2.string类对象的容量操作
●3.string类对象的访问及遍历操作
●4.string类对象的修改操作
●5.string类非成员函数
●6.string类的模拟实现
1.string类对象的常见构造
| 函数名称 | 功能说明 |
|---|---|
| string() | 构造空的string类对象,即空字符串 |
| string(const char* s) | 用C-string来构造string类对象 |
| string(size_t n, char c) | string类对象中包含n个字符c |
| string(const string&s) | 拷贝构造函数 |
示例:
void test1()
{
string s1;
string s2("hello world!");
string s3(5, 'c');
string s4(s2);
cout << s1 << endl; //
cout << s2 << endl; //hello world!
cout << s3 << endl; //ccccc
cout << s4 << endl; //hello world!
}
2.string类对象的容量操作
| 函数名称 | 功能说明 |
|---|---|
| size | 返回字符串有效字符长度 |
| length | 返回字符串有效字符长度 |
| capacity | 返回空间总大小 |
| empty | 检测字符串释放为空串,是返回true,否则返回false |
| clear | 清空有效字符 |
| reserve | 为字符串预留空间 |
| resize | 将有效字符的个数该成n个,多出的空间用字符c填 |
示例:
void test2()
{
string s = "hello world!";
cout << s << endl; //hello world!
cout << s.size() << endl; //12
cout << s.length() << endl; //12
cout << s.capacity() << endl; //15
cout << s.empty() << endl; //0
s.reserve(30);
cout << s.capacity() << endl; //31
s.resize(20,'+');
cout << s << endl; //hello world!++++++++
s.resize(10);
cout << s << endl; //hello worl
s.clear();
}
3.string类对象的访问及遍历操作
| 函数名称 | 功能说明 |
|---|---|
| operator[] | 返回pos位置的字符,const string类对象调用 |
| begin+end | begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器 |
| rbegin+rend | begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器 |
| 范围for | C++11支持更简洁的范围for的新遍历方式 |
示例:
void test3()
{
string s = "hello world!";
for (int i = 0; i < s.size(); i++)
{
cout << s[i];
}
cout << endl;//hello world!
for (string::iterator i = s.begin(); i != s.end(); i++)
{
cout << *i;
}
cout << endl;//hello world!
for (string::reverse_iterator i = s.rbegin(); i != s.rend(); i++)
{
cout << *i;
}
cout << endl;//!dlrow olleh
for (auto& e : s)
{
cout << e;
}
cout << endl;//hello world!
}
4.string类对象的修改操作
| 函数名称 | 功能说明 |
|---|---|
| push_back | 在字符串后尾插字符c |
| append | 在字符串后追加一个字符串 |
| operator+= | 在字符串后追加字符串str |
| c_str | 返回C格式字符串 |
| find+npos | 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置 |
| rfind | 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置 |
| substr | 在str中从pos位置开始,截取n个字符,然后将其返回 |
示例:
void test4()
{
string s ;
s.push_back('a');
s.push_back('b');
s.push_back('c');
s.push_back('d');
print_string(s); //abcd
s.append("efgh");
print_string(s); //abcdefgh
s += "ijkm";
print_string(s); //abcdefghijkm
const char *c = s.c_str();
for (int i = 0; i < s.size(); i++)
{
cout << c[i];
}
cout << endl; //abcdefghijkm
cout << s.find('a') << endl; //0
cout << s.rfind('m') << endl; //11
cout << s.substr(0, 3) << endl; //abc
}
5.string类非成员函数
| 函数名称 | 功能说明 |
|---|---|
| operator+ | 尽量少用,因为传值返回,导致深拷贝效率低 |
| operator>> | 输入运算符重载 |
| operator<< | 输出运算符重载 |
| getline | 获取一行字符串 |
| relational operators | 大小比较 |
示例:
void test5()
{
string firstlevel("com");
string secondlevel("string");
string scheme("http://");
string hostname;
string url;
hostname = "www." + secondlevel + '.' + firstlevel;
url = scheme + hostname;
cout << url << endl;//http://www.string.com
string name;
cout << "Please, enter your full name: :";
cin >> name;
cout << "Your name is :"<<name << endl;
std::cout << "Please, enter your full name: ";
std::getline(std::cin, name);
std::cout << "Hello, " << name << "!\n";
string s1 = "football";
string s2 = "basketball";
if (s1 > s2) {
cout << "s1 > s2" << endl; //s1 > s2
}
else if (s1 < s2) {
cout << "s1 < s2" << endl;
}
else {
cout << "s1 = s2" << endl;
}
}
6.string类的模拟实现
示例代码:string.hpp(源头不分离)
#pragma once
#include<cstring>
#include<assert.h>
namespace myString
{
class string
{
public:
typedef char* iterator;
typedef const char* const_iterator;
/*string s*/
string()
:_str(new char[1])
{
_str[0] = '\0';
_size = 0;
_capacity = 0;
}
/*string s("hello world")*/
string(const char* str)
:_str(new char[strlen(str)+1])
,_size(strlen(str))
,_capacity(strlen(str))
{
strcpy(_str, str);
}
/*string s(s1)*/
string(const string &s)
{
_str = new char[s.capacity()+1];
strcpy(_str,s._str);
_size = s.capacity();
_capacity = s.capacity();
}
void swap(string &s)
{
std::swap(_str, s._str);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
/*s=s1*/
string& operator=(string s)
{
swap(s);
return *this;
}
~string()
{
delete[] _str;
_str = NULL;
_size = 0;
_capacity = 0;
}
iterator begin()
{
return _str;
}
iterator end()
{
return _str + _size;
}
const_iterator begin() const
{
return _str;
}
const_iterator end() const
{
return _str + _size;
}
const char* c_str() const
{
return _str;
}
size_t size() const
{
return _size;
}
size_t capacity() const
{
return _capacity;
}
char& operator[](size_t pos)
{
/*合法性判断*/
assert(pos>=0&&pos<=_capacity);
return _str[pos];
}
const char& operator[](size_t pos) const
{
/*合法性判断*/
assert(pos >= 0 && pos <= _capacity);
return _str[pos];
}
/*Requests that the string capacity be adapted to a planned change in size to a length of up to n characters.*/
/*不缩容,只去扩容*/
void reserve(size_t n=0)
{
if (n > _capacity)
{
char* tmp = new char[n + 1];
strcpy(tmp,_str);
delete[] _str;
_str = tmp;
_capacity = n;
}
}
void push_back(char c)
{
if (_size+1>_capacity)
{
/*这里采用的是每次只扩容一个,也可以每次扩容更大的空间*/
reserve(_size+1);
}
_str[_size] = c;
_size++;
_str[_size] = '\0';
}
void append(const char *str)
{
int len = strlen(str);
if (_size+len>_capacity)
{
reserve(_size+len);
}
strcpy(_str+_size,str);
_size += len;
}
string& operator+=(char ch)
{
push_back(ch);
return *this;
}
string& operator+=(const char *str)
{
append(str);
return *this;
}
void insert(size_t pos,const char c)
{
assert(pos >= 0 && pos <= _capacity);
if (_size + 1 > _capacity)
{
reserve(_size+1);
}
/*hello world->hellox world*/
size_t end = _size + 1;
while (end>pos)
{
_str[end] = _str[end-1];
end--;
}
_str[pos] = c;
_size++;
}
void insert(size_t pos,const char *s)
{
assert(pos >= 0 && pos <= _capacity);
int len = strlen(s);
if (_size+len>_capacity)
{
reserve(_size + len);
}
size_t end = _size + len;
while (end>pos)
{
_str[end] = _str[end - len];
end--;
}
strncpy(_str + pos, s,len);
_size += len;
}
void erase(size_t pos, size_t len = npos)
{
assert(pos >= 0 && pos <= _capacity);
if (len == npos || pos + len >= _size)
{
_str[pos] = '\0';
_size = pos;
}
/*hello world->hello ld*/
else
{
strcpy(_str+pos,_str+pos+len);
_size -= len;
}
}
size_t find(const char c,size_t pos=0)
{
for (int i = pos; i < _size; i++)
{
if (_str[i] == c)
{
return i;
}
}
return npos;
}
size_t find(const char* s,size_t pos=0)
{
const char* pch = strstr(_str+pos,s);
if (pch == nullptr){
return npos;
}
else{
return pch - _str;
}
}
string substr(size_t pos=0,size_t len=npos)
{
assert(pos >= 0 && pos <= _capacity);
size_t end = pos + len;
if (len == npos || pos + len >= _size)
{
end = _size;
}
string subs;
subs.reserve(len);
for (size_t i = pos; i < end; i++)
{
subs += _str[i];
}
return subs;
}
void clear()
{
_size = 0;
_str[0] = '\0';
}
private:
char* _str;
size_t _size;
size_t _capacity;
const static size_t npos=-1;
};
ostream& operator<<(ostream& out,const string &s)
{
for (auto ch : s)
{
out << ch;
}
return out;
}
istream& operator>>(istream& in,string &s)
{
s.clear();
char ch = in.get();
while(ch!='\n'&&ch!=' ')
{
in >> ch;
ch = in.get();
}
return in;
}
}
<您的三连和关注是我最大的动力>
🚀 文章作者:张同学的IT技术日记
分类专栏:C++系列