在C语言中其实是没有字符串这个类型的,使用字符串的时候用字符数组,在C++中引入了string这个字符串类型,这个类型更加的快捷和方便、我们可以学习如何使用以及了解底层是如何实现的。
使用时包含头文件#include <string>
和using namespace std
string类的构造函数
string() //构造空的string对象,空字符
string(const char* s) //用C-string来构造string类
string(size_t n,char c)//用n个字符c来初始化构造string类
string(const string& s)//拷贝构造
string类对象容器的操作
size() //返回字符串有效字符长度
length() //返回字符串有效字符长度,与size()相同
capacity()//返回空间总大小
empty() //检测字符串是否为空串
clear() //清理有效字符
reserve()//为string类对象预开辟空间
resize()//为string类对象预开辟空间并初始化。
string类对象内容的增删查改函数
push_back() //在字符串后尾插字符c
append() //在字符串后追加字符串
operator+= //在字符串后追加字符串
c_str() //返回c格式字符串
find() //从pos位置开始向后查找字符c,然后返回位置
rfind() //从pos位置开始向前查找字符c,然后返回位置
substr() //在str中从pos位置开始,截取n个字符,然后将其返回。
string重载了一些运算符操作,例如:
[]、>=、>、<、<=、+、+=、=、==、!=、<<、>>
迭代器的使用
//普通迭代器
string s("hello world");
string::iterator it = s.begin();
while(it!=s.end()){
cout<<*it<<" ";
it++;
}
cout<<endl;
//范围for,底层也是迭代器
for(auto& e: s){
cout<<s<<" ";
}
cout<<endl;
string的模拟实现
class string {
public:
//迭代器,底层还是char* 类型的指针。
typedef char* iterator;
typedef const char* const_iterator;
string(const char* str = "") {
_a = new char[strlen(str)+16];
strcpy(_a, str);
_size = strlen(str);
_capacity = strlen(str) + 16;
}
string(const string& s) {
_a = new char[s._capacity];
strcpy(_a, s._a);
_size = s._size;
_capacity = s._capacity;
}
string& operator=(const string& s) {
_a = new char[s._capacity];
strcpy(_a, s._a);
_size = s._size;
_capacity = s._capacity;
return *this;
}
~string() {
delete[] _a;
_size = _capacity = 0;
}
iterator begin() {
return _a;
}
const_iterator begin() const{
return _a;
}
iterator end() {
return _a + _size;
}
const_iterator end() const{
return _a + _size;
}
void push_back(char c) {
if (_size+1 >= _capacity) {
reserve(2 * _capacity);
}
_a[_size] = c;
_size++;
_a[_size] = '\0';
}
string& operator+=(char c) {
push_back(c);
return *this;
}
void append(const char* str) {
if (_size + strlen(str) > _capacity) {
reserve(2 * _capacity);
}
strcpy(_a + _size, str);
_size += strlen(str);
}
string& operator+=(const char* str) {
append(str);
return *this;
}
void clear() {
_a[0] = '\0';
_size = 0;
}
void swap(string& s)
{
std::swap(_a, s._a);
std::swap(_size, s._size);
std::swap(_capacity, s._capacity);
}
const char* c_str()const
{
return _a;
}
size_t size()const
{
return _size;
}
size_t capacity()const
{
return _capacity;
}
bool empty()const
{
return _size == 0;
}
char& operator[](size_t index) {
return _a[index];
}
const char& operator[](size_t index) const{
return _a[index];
}
bool operator<(const string& s) {
return strcmp(_a, s._a) < 0;
}
bool operator<=(const string& s) {
return *this < s || *this == s;
}
bool operator>(const string& s) {
return strcmp(_a, s._a) > 0;
}
bool operator>=(const string& s) {
return *this > s || *this == s;
}
bool operator==(const string& s) {
return strcmp(_a, s._a) == 0;
}
bool operator!=(const string& s) {
return !(*this == s);
}
size_t find(char c, size_t pos = 0)const {
while (pos < _size) {
if (c == _a[pos])
return pos;
pos++;
}
return npos;
}
size_t find(const char* s, size_t pos = 0) {
return strstr(_a, s)-begin();
}
string& insert(size_t pos, char c) {
if (_size >= _capacity)
reserve(2 * _capacity);
size_t next = _size+1;
while (next > pos) {
_a[next] = _a[next-1];
--next;
}
_a[next] = c;
_size++;
return *this;
}
string& insert(const char* s, size_t pos)
{
int len = strlen(s);
if (_size + len >= _capacity) {
reserve(_size + len + 1);
}
size_t next = _size+len;
while (next >= pos+len) {
_a[next] = _a[next-len];
--next;
}
strncpy(_a + pos, s,len);
_size += len;
return *this;
}
string& erase(size_t pos, size_t len=npos) {
int next = pos + len;
if (len == npos) {
_a[pos] = '\0';
_size = pos;
}
else {
/*while (next <= _size) {
_a[next - len] = _a[next];
next++;
}*/
strcpy(_a + pos, _a + pos + len);
_size -= len;
}
return *this;
}
void resize(size_t n, char c = '\0') {
if (n < _size) {
_a[n] = '\0';
_size = n;
}
else {
if (n > _capacity)
reserve(n);
memset(_a + _size+1, c, n - _size-2);
}
}
void reserve(size_t n) {
if (n > _capacity) {
char* tem = new char[n];
strcpy(tem, _a);
delete[] _a;
_a = tem;
_capacity = n;
}
}
private:
char* _a;
size_t _size;
size_t _capacity;
static const size_t npos;
};
const size_t string::npos = -1;
std::ostream& operator<<(std::ostream& out, const string& s)
{
for (auto ch : s) {
out << ch;
}
return out;
}
std::istream& operator>>(std::istream& in, string& s) {
s.clear();
char ch = in.get();
//定义一个缓冲区
char buff[128];
size_t i = 0;
while (ch != ' ' && ch != '\n') {
buff[i++] = ch;
if (i == 127) {
buff[127] = '\0';
s += buff;
i = 0;
}
ch = in.get();
}
//如果最后buff里面还有数据,刷新到类对象里面
if (buff != 0) {
buff[i] = '\0';
s += buff;
}
return in;
}
这就是string类的使用和模拟实现,希望对您有所帮助。