目录

C++ string类

string类的常用接口说明

string类(实现常用接口)


C++ string类

值得注意的是 , string不是STL的容器,string是basic_string类模板的一个实例,string是一个模板类, 它使用char来实例basic_string, string集成的操作函数与STL中容器中的操作函数大部分很相似, 因为sting本身也是用顺序表来实现的(与vector容器类似)

C++之所以用C++标准程序库中的string来代替C中的char*(C++中还是可以用char*, 这是为了与C保持兼容),是因为它和C中的char*比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下的需要。我们也可以把string看成是C++的基本数据类型。
string定义在标准命名空间std中, 所以要么在用之前加using namespace std; 使string对外可见, 要么不嫌麻烦 std::string
使用string这个模板类要加头文件<string>

注意:

1. string是表示字符串的字符串类
2.string的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。
3. string在底层实际是:basic_string模板类的别名,typedef basic_string<char, char_traits, allocator>string;
4. 不能操作多字节或者变长字符的序列(举个例子, string s = "你好"; 当你pop_back()时, 并不是删除字符 "好", 而是只删除char类型的的长度也就是1字节, 而汉字在常见编码方式下都比1字节长)

string类的常用接口说明

string其中大部分接口与矢量容器vector接口保持一致, 功能用法也一样, 这些与vector保持一致接口用起来就与vector<char> 一样, 这里对这些保持一致的接口并不做过多的说明   , string可以看做在vector<char>的基础上多了一些处理字符串的接口函数                 链接 :vector接口说明

1. string类对象的常见构造

函数名称 函数功能
string ()

构造一个空的字符串

string (const char* c_s) 用一个char*类型的字符串c_s来构造一个string类型的的字符串
string(const char* c_s, size_t n) 截取c_s中前n个字符,  来构造字符串
string (const char* c_s, size_t pos, size_t npos) 截取c_s中从下标为pos的字符到下标为npos的字符, 来构造字符串
string (const string& s) 拷贝构造函数, 构造一个与s一模一样的字符串
string (const string& s, size_t pos) 截取s中从下标为pos的字符开始往后的所有有效字符, 来构造字符串
string (const string& s, size_t pos, size_t npos) 截取s中从下标为pos的字符到下标为npos的字符, 来构造字符串
string (size_t n, char c) 构造一个有n个字符c的字符串

template <class InputIterator>

string (InputIterator begin, InputIterator end)

以区间[begin, end)  (不包含end)内的字符作为字符串s的初值, 这里的begin和end是迭代器 
~string() 析构

来看具体应用 :

//头文件

#include<iostream>
#include<string>
#include <typeinfo>
using namespace std;
void test() {//string的构造函数string s;//string()string s1("abcdef");//string(const char* s)string s2(4, 'a');   //string(size_t n, char c)string s3(s1);        //string(const string& s)string s4(s1, 3);  //string(const string& s, size_t n)string s5(s1, 1, 5);string s6("abcdefe", 3);string s7("scscssr", 2, 6);cout << typeid(s1.begin()).name() << endl;cout << typeid(*s1.begin()).name() << endl;string::iterator begin = s1.begin();string::iterator end = s1.end();string s8(begin, end);cout << "s: " << endl<< "s1:" << s1 << endl<< "s2:" << s2 << endl<< "s3:" << s3 << endl<< "s4:" << s4 << endl<< "s5:" << s5 << endl<< "s6:" << s6 << endl<< "s7:" << s7 << endl<< "s8:" << s8 << endl;for (int i = 0; begin + i < end; ++i) {cout << *(begin + i);}cout << endl;cout << endl;system("pause");system("cls");
}

值得注意的是最后一个函数 string (string::iterator begin, string::iterator end), 其中两个参数都是迭代器, 迭代器是一个变量, 迭代器可以指向string中的某个元素,通过迭代器就可以读写它指向的元素。从这一点上看,迭代器和指针类似。可以看到string中的迭代器变量解引用之后是char类型, 本质上迭代器就是char*类型 .

2. string类对象的容量操作

函数名称 函数功能
size_t size() const 返回字符串有效字符长度
size_t length() const 返回字符串有效字符长度
size_t capacity ( ) const 返回空间总大小
bool empty ( ) const 检测字符串是否为空串,是返回true,否则返回false
void clear() 清空有效字符(将字符串变成空串)
void resize ( size_t n, char c = 0 ) 将有效字符的个数(size)改成n个,多出的空间用字符c填充(注意, 字符个数只会增加, 如传入比有效长度小的值则不作操作)
void resize ( size_t  n ) 将有效字符的个数(size)改成n个,多出的空间用字符'\0'填充(注意, 字符个数只会增加, 如传入比有效长度小的值则不作操作)
void reserve ( size_t n = 0 ) 为字符串预留空间(扩容, 改变的是容量(capacity)的大小)(注意, 扩容只会增加, 如传入比原容量小的值则不作操作)

注意 :

size函数和length作用是一样的

resize和reserve都只能向大调整

resize函数会调用reserve函数

void test1() {string s1("abcdef");//string(const char* s)string s2(4, 'a');  //string(size_t n, char c)string s3(s1);        //string(const string& s)cout << "sting类的容量操作\n";cout << "s1有效长度是:" << s1.size() << endl;//size_t size() const 返回字符串有效字符长度cout << "s1有效长度是:" << s1.length() << endl;//size_t length() const 返回字符串有效字符长度cout << "s2有效长度是:" << s2.size() << endl;cout << "s2有效长度是:" << s2.length() << endl;cout << "s1的容量是:" << s1.capacity() << endl;//size_t capacity() const 返回空间总大小cout << "s2的容量是:" << s2.capacity() << endl;s1.reserve(20);//void reserve(size_t res_arg = 0) 为字符串预留空间cout << "s1有效长度是:" << s1.size() << endl;cout << "s1的容量是:" << s1.capacity() << endl;s2.resize(25);//void resize(size_t n) 将有效字符的个数改成n个,多出的空间用0填充cout << "s2有效长度是:" << s2.size() << endl;cout << "s2的容量是:" << s2.capacity() << endl;s2 += "字符串结束";cout << "s2:" << s2 << endl;s3.resize(20, 'z');//void resize(size_t n, char c) 将有效字符的个数该成n个,多出的空间用字符c填充cout << "s3有效长度是:" << s3.size() << endl;cout << "s3的容量是:" << s3.capacity() << endl;cout << "s3:" << s3 << endl;s1.empty() ? cout << "s1为空\n" : cout << "s1不为空!\n";//bool empty() const 检测字符串释放为空串,是返回true,否则返回falsecout << "清空s2\n";s2.clear();s2.empty() ? cout << "s2为空\n" : cout << "s2不为空!\n";system("pause");system("cls");
}

3.string类对象的访问操作

函数名称 函数功能
char& operator[] ( size_t pos ) 返回pos位置的字符,const string类对象调用
const char& operator[] (size_t pos) const 返回pos位置的字符,非const string类对象调用
void test2() {//string类对象的访问操作string s1("abcdef");const string s2("xyz");cout << "s1:" << s1 << endl;for (size_t i = 0; i < s1.size(); ++i) {cout << s1[i] << " ";//char& operator[] ( size_t pos ) 返回pos位置的字符,非const string类对象调用}cout << endl;cout << "s2:" << s2 << endl;for (size_t i = 0; i < s2.size(); ++i) {cout << s2[i] << " ";//char& operator[] ( size_t pos ) 返回pos位置的字符,const string类对象调用}cout << endl;system("pause");system("cls");
}

 4. string类对象的修改操作

函数名称 重载函数 函数功能
void push_back(char c) / 在字符串后尾插字符c
string& append

string& append (const string& str);

string& append (const string& str, size_t subpos, size_t sublen);

string& append (const char* s);

string& append (const char* s, size_t n);

string& append (size_t n, char c);

template <class InputIterator>

string& append (InputIterator first, InputIterator last);

在字符串后尾插字符或字符串
string& operator+=

string& operator+= (const string& str);

string& operator+= (const char* s);

string& operator+= (char c);

在字符串后追加一个字符串s在字符串后追加一个C字符串s

在字符串后追加字符c

const char* c_str( )const  / 返回C格式字符串
size_t find 

size_t find (const string& str, size_t pos = 0) const;

size_t find (const char* s, size_t pos = 0) const;

size_t find (const char* s, size_t pos, size_t n) const;

size_t find (char c, size_t pos = 0) const;

从字符串pos位置开始往后找字符或字符串,返回其在此字符字符串中的位置
size_t rfind

size_t rfind (const string& str, size_t pos = npos) const;

size_t rfind (const char* s, size_t pos = npos) const;

size_t rfind (const char* s, size_t pos, size_t n) const;

size_t rfind (char c, size_t pos = npos) const;

从字符串pos位置开始往前找字符或字符串,返回其在此字符串中的位置
string substr(size_t pos = 0, size_t n = npos)const / 在str中从pos位置开始,往后截取n个字符,然后返回内容是这n个字符的字符串
void test3() {string s("abcdef");string s1("higk");string s2("qrst");cout << "s:" << s << endl;s.push_back('g');//void push_back(char c) 在字符串后尾插字符ccout << "s:" << s << endl;s.append(s1);//string& append (const char* s); 在字符串后追加一个字符串s.append("dsscs");s.append(8, 'a');cout << "s:" << s << endl;s += "lmnop";//string& operator+=(const char* s) 在字符串后追加一个字符串cout << "s:" << s << endl;s += s2;//string& operator+=(const string& str)在字符串后追加sting类字符串strcout << "s:" << s << endl;s += 'u';//string& operator+=(char c) 在字符串后追加字符ccout << "s:" << s << endl;s.pop_back();//void pop_back() 删除字符串最后一个字符cout << "s:" << s << endl;const char* c_s = s1.c_str();//const char* c_str( )const 返回C格式字符串cout << "c_s:" << c_s << endl;char c = 'd';size_t pos = 0;size_t n = s.find(c, pos);//pos<s.size();否则会发生访问越界//size_t find (char c, size_t pos =0)const //pos是缺省参数, 不传就是从0开始//从字符串pos位置开始往后找字符c,找到字符返回字符串中的下标,找不到返回-1, //因为返回值是size_t所以是4294967295n != (size_t)-1 ? cout << c << "在字符串s中下标为" << n << "的位置\n" :cout << c << "不在从下标" << pos << "位置开始往后的字符串中\n";n = s.find(s1/*缺省参数默认0*/);//pos<s.size();否则会发生访问越界//size_t find (string c, size_t pos =0)const //pos是缺省参数, 不传就是从0开始//从字符串pos位置开始往后找字串c,找到字符串c//返回c在被找字符串中的下标,找不到返回-1, 因为返回值是size_t所以是4294967295n != (size_t)-1 ? cout << s1 << "在字符串s中下标为" << n << "的位置\n" :cout << s1 << "不在从下标" << pos << "位置开始往后的字符串中\n";n = s.rfind(c_s, s.size() - 1);//pos<s.size();否则会发生访问越界//size_t find (char* c, size_t pos =0)const //pos是缺省参数, 不传就是从0开始//从字符串pos位置开始往后找字串c,找到字符串c//返回c在被找字符串中的下标,找不到返回-1, 因为返回值是size_t所以是4294967295n != (size_t)-1 ? cout << c_s << "在字符串s中下标为" << n << "的位置\n" :cout << c_s << "不在从下标" << pos << "位置开始往后的字符串s中\n";size_t npos = 10;n = s.rfind(c, npos);//npos<s.size();否则会发生访问越界//size_t rfind (char c, size_t pos =0)const//pos是缺省参数, 默认为0//从字符串pos位置开始往前找字符c//找到字符返回字符串中的下标,找不到返回-1, 因为返回值类型size_t所以是4294967295n != (size_t)-1 ? cout << c << "在字符串s中下标为" << n << "的位置\n" :cout << c << "不在从下标" << npos << "位置开始往前的字符串中\n";string s3 = s.substr(pos, npos);//npos<s.size(), pos>=0, npos-pos>=0;//pos为缺省参数//string substr(size_t pos = 0, size_t n= npos)const//在str中从pos位置开始,截取n个字符,然后将其返回cout << "s3:" << s3 << endl;system("pause");system("cls");
}

注意 :

在string尾部追加字符时,s.push_back('c') , s.append(1, 'c') , s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。

对string操作时,如果能够大概预估到放多少字符,可以先通过reserve()函数把空间预留好, 这样就不会出现后期操作中频繁扩容,导致效率降低的情况发生

5. string类非成员函数(友元函数)

函数名称 重载的函数 函数功能
operator+

string operator+ (const string& lhs, const string& rhs);

string operator+ (const string& lhs, const char*   rhs);

string operator+ (const char*   lhs, const string& rhs);

string operator+ (const string& lhs, char rhs);

string operator+ (char lhs, const string& rhs);

返回字符(串)+字符(串)

此函数效率较低

operator<< ostream& operator<< (ostream& os, const string& str); 输出运算符重载, 打印字符串
operator>> istream& operator>> (istream& is, string& str); 输入运算符重载, 输入字符串
getline istream& getline (istream& is, string& str, char delim); istream& getline (istream& is, string& str);  获取一行字符串, char delim, 是结束符标识.
relational operators

bool operator== (const string& lhs, const string& rhs);

bool operator== (const char*   lhs, const string& rhs);

bool operator== (const string& lhs, const char*   rhs);

bool operator!= (const string& lhs, const string& rhs);

bool operator!= (const char*   lhs, const string& rhs);

bool operator!= (const string& lhs, const char*   rhs);

bool operator<  (const string& lhs, const string& rhs);

bool operator<  (const char*   lhs, const string& rhs);

bool operator<  (const string& lhs, const char*   rhs);

bool operator<= (const string& lhs, const string& rhs);

bool operator<= (const char*   lhs, const string& rhs);

bool operator<= (const string& lhs, const char*   rhs);

bool operator>  (const string& lhs, const string& rhs);

bool operator>  (const char*   lhs, const string& rhs);

bool operator>  (const string& lhs, const char*   rhs);

bool operator>= (const string& lhs, const string& rhs);

bool operator>= (const char*   lhs, const string& rhs);

bool operator>= (const string& lhs, const char*   rhs);

比较两个字符串

string和char*比较

char*和string比较

string和string比较


string类(实现常用接口)

string.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<string>
#include<cstring>
#include<cassert>
using namespace std;
class String {size_t m_capacity;char* m_data;size_t m_size;
public:typedef char* Iterator;//using Iterator = typename String::Iterator;String();String(const String&);String(const char*);String(size_t, char);String(const String&, size_t);String& operator=(const String&);String& operator=(const char*);template <class InputIterator>String(InputIterator begin, InputIterator end) :m_size(0), m_capacity(15), m_data(new char[m_capacity]){reserve(end - begin);m_size = end - begin;strncpy(m_data, begin, end - begin);}~String();Iterator begin()const;Iterator end()const;size_t size() const;size_t length() const;size_t capacity() const;bool empty() const;void clear();void resize(size_t n, const char c = ' ');void reserve(size_t res_arg);char& operator[] (size_t pos) const;char& operator[] (size_t pos);void push_back(const char c);void pop_back(const char c);String& append(const char* s);String& append(size_t n, const char c);String& append(const String& s);template <class InputIterator>String& append(InputIterator first, InputIterator last) {int size = last - first + m_size;reserve(size);strncpy(m_data + m_size, first, last - first);m_size = size;return *this;}const char* c_str()const;size_t find(const char c, size_t pos = 0)const;size_t find(const char* c, size_t pos = 0)const;size_t find(const String& t, size_t pos = 0)const;size_t rfind(const char c, size_t pos = 0)const;size_t rfind(const char* s, size_t pos = 0)const;size_t rfind(const String& t, size_t pos = 0)const;String substr(size_t pos = 0, size_t n = 0)const;String& operator+=(const char c);String& operator+=(const String& s);String& operator+=(const char* s);friend String operator+(const char* s, const String& t);String operator+(const char* s)const;String operator+(const String& t)const;bool operator<(const String& t)const;bool operator>(const String& t)const;bool operator<=(const String& t)const;bool operator>=(const String& t)const;bool operator==(const String& t)const;bool operator!=(const String& t)const;bool operator<(const char* s)const;bool operator>(const char* s)const;bool operator<=(const char* s)const;bool operator>=(const char* s)const;bool operator==(const char* s)const;bool operator!=(const char* s)const;friend bool operator<(const char* t1, const String& t2);friend bool operator>(const char* t1, const String& t2);friend bool operator<=(const char* t1, const String& t2);friend bool operator>=(const char* t1, const String& t2);friend bool operator==(const char* t1, const String& t2);friend bool operator!=(const char* t1, const String& t2);friend istream& operator>>(istream& is, String& t);friend ostream& operator<<(ostream& os, const String& t);friend istream& getline(istream&  is, String& str, char n);friend istream& getline(istream&  is, String& str);
};

string.cpp

#include "string.h"
String::Iterator String::begin()const {return m_data;
}
String::Iterator String::end() const{return m_data + m_size;
}
String::String() :m_size(0),m_capacity(15),m_data(new char[m_capacity])
{memset(m_data, 0, m_capacity);
}
String::String(const String& t):m_size(0),m_capacity(15),m_data(new char[m_capacity])
{if (this == &t) {return;}memset(m_data, 0, m_capacity);reserve(t.m_capacity);m_size = t.m_size;m_capacity = t.m_capacity;strncpy(m_data, t.m_data, m_size);
}
String::String(const char* t) :m_size(0), m_capacity(15), m_data(new char[m_capacity])
{if (t == nullptr) {assert(false);}size_t size = strlen(t);reserve(size);m_size = size;strcpy(m_data, t);
}
String::String(size_t n, char c) :m_size(0), m_capacity(15), m_data(new char[m_capacity])
{reserve(n);m_size = n;memset(m_data, c, n);
}
String::String(const String& t, size_t n) :m_size(0), m_capacity(15), m_data(new char[m_capacity])
{reserve(n);m_size = n;strncpy(m_data, t.m_data, n);
}
String::~String() { if (m_data) {delete[]m_data;}m_data = nullptr;m_size = 0;m_capacity = 0;
}
String& String::operator=(const String& t) {if (this == &t) {return *this;}reserve(t.m_capacity);strcpy(m_data, t.m_data);m_size = t.m_size;return *this;
}
String& String::operator=(const char* s) {if (s == nullptr) {assert(false);}if (!strcmp(m_data, s)) {return *this;}size_t size = strlen(s) + m_size;reserve(size);m_size = size;strcpy(m_data, s);return *this;
}
size_t String::size() const {return m_size;
}
size_t String::length() const {return m_size;
}
size_t String::capacity() const {return m_capacity;
}
bool String::empty() const {return m_size == 0;
}
void String::clear() {m_size = 0;
}
void String::resize(size_t n, const char c) {if (n > m_size) {size_t m = m_size;reserve(n);m_size = n;/*for (size_t i = m - 1; i < m_size; ++i) {m_data[i] = c;}*/memset(m_data + m, c, m_capacity - m);}
}
void String::reserve(size_t res_arg = 0) {if (res_arg > m_capacity) {m_capacity = (res_arg / m_capacity + 1) * 16 - 1;m_data = (char*)realloc(m_data, m_capacity);memset(m_data + m_size, 0, m_capacity - m_size);}
}char& String::operator[] (size_t pos) const {return m_data[pos];
}
char& String::operator[] (size_t pos) {return m_data[pos];
}
void String::push_back(const char c) {reserve(m_size);m_data[m_size++] = c;
}
void String::pop_back(const char c) {if (m_size) {--m_size;}
}
String& String::append(const char* s) {if (s == nullptr) {assert(false);}int size = strlen(s) + m_size;reserve(size);strcpy(m_data + m_size, s);m_size = size;return *this;
}
String& String::append(size_t n, const char c) {while (n--) {push_back(c);}return *this;
}
String& String::append(const String& str) {int size = str.m_size + m_size;reserve(size);strncpy(m_data + m_size, str.m_data, str.m_size);m_size = size;return *this;
}
String& String::operator+=(const String&str) {int size = str.m_size + m_size;reserve(size);strncpy(m_data + m_size, str.m_data, str.m_size);m_size = size;return *this;
}
String& String::operator+=(const char* s) {if (s == nullptr) {assert(false);}int size = strlen(s) + m_size;reserve(size);strcpy(m_data + m_size, s);m_size = size;return *this;
}
String& String::operator+=(const char c) {push_back(c);return *this;
}
String operator+(const char* s, const String& t) {if (s == nullptr) {assert(false);}String res;res = s;int size = res.m_size + t.m_size;res.reserve(size);strncpy(res.m_data + res.m_size, t.m_data, t.m_size);res.m_size = size;return res;
}String String::operator+(const char* s)const {if (s == nullptr) {assert(false);}String res = *this;int size = strlen(s) + m_size;res.reserve(size);strcpy(res.m_data + res.m_size, s);res.m_size = size;return res;
}
String String::operator+(const String& t)const {String res = *this;int size = res.m_size + t.m_size;res.reserve(size);strncpy(res.m_data + res.m_size, t.m_data, t.m_size);res.m_size = size;return res;
}
const char* String::c_str()const {return m_data;
}
size_t String::find(const char c, size_t pos)const {if (pos < 0 || pos >= m_size) {return -1;}char* tmp = strchr(m_data + pos, c);if (tmp) {return tmp - m_data;}else {return -1;}
}
size_t String::find(const char* c, size_t pos) const {if (c == nullptr) {assert(false);}if (pos < 0 || pos >= m_size) {return -1;}char* tmp = strstr(m_data + pos, c);if (tmp) {return tmp - m_data;}else {return -1;}
}
size_t String::find(const String& t, size_t pos)const {if (pos < 0 || pos >= m_size) {return -1;}char* tmp = strstr(m_data + pos, t.m_data);if (tmp) {return tmp - m_data;}else {return -1;}
}
size_t String::rfind(const char c, size_t pos)const{char* tmp = nullptr;strncpy(tmp, m_data, pos);char* m = nullptr;if (tmp) {m = strchr(tmp, c);}if (m) {return m - tmp;}else {return -1;}
}
size_t String::rfind(const char* s, size_t pos)const {if (s == nullptr) {assert(false);}char* tmp = nullptr;strncpy(tmp, m_data, pos);char* m = nullptr;if (tmp) {m = strstr(tmp, s);}if (m) {return m - tmp;}else {return -1;}
}
size_t String::rfind(const String& t, size_t pos)const {char* tmp = new char[pos + 1];tmp[pos] = 0;strncpy(tmp, m_data, pos);char* m = nullptr;if (tmp) {m = strstr(tmp, t.c_str());}if (m) {return m - tmp;delete[]tmp;}else {return -1;delete[]tmp;}
}
String String::substr(size_t pos, size_t n)const {String res;if (pos > m_size)return res;if (pos + n > m_size) {n = m_size - pos;}res.reserve(n);res.m_size = n;strncpy(res.m_data, m_data + pos, n);return res;
}
istream& operator>>(istream& is, String& t) {char ch;t.m_size = 0;is >> ch;while (ch != '\n') {t.push_back(ch);ch = getchar();}return is;
}
ostream& operator<<(ostream& os, const String& t) {for (auto i : t) { os << i;}return os;
}
istream& getline(istream&  is, String& t, char n) {char ch;t.m_size = 0;is >> ch;while (ch != n) {t.push_back(ch);ch = getchar();}return is;
}
istream& getline(istream&  is, String& t) {char ch;t.m_size = 0;is >> ch;while (ch != '\n') {t.push_back(ch);ch = getchar();}return is;
}bool String::operator<(const String& t)const {size_t n;m_size < t.m_size ? n = m_size : n = t.m_size;return strncmp(m_data, t.m_data, n) < 0;
}
bool String::operator>(const String& t)const {size_t n;m_size < t.m_size ? n = m_size : n = t.m_size;return strncmp(m_data, t.m_data, n) > 0;
}
bool String::operator<=(const String& t)const {//size_t n;//m_size < t.m_size ? n = m_size : n = t.m_size;//return strncmp(m_data, t.m_data, n) < 0 || m_size == t.m_size && !strncmp(m_data, t.m_data, n);return *this < t || *this == t;
}
bool String::operator>=(const String& t)const {//size_t n;//m_size < t.m_size ? n = m_size : n = t.m_size;//return strncmp(m_data, t.m_data, n) > 0 || m_size == t.m_size && !strncmp(m_data, t.m_data, n);return *this > t || *this == t;
}
bool String::operator==(const String& t)const {size_t n;m_size < t.m_size ? n = m_size : n = t.m_size;return m_size == t.m_size && !strncmp(m_data, t.m_data, n);
}
bool String::operator!=(const String& t)const {//size_t n;//m_size < t.m_size ? n = m_size : n = t.m_size;//return m_size != t.m_size || !strncmp(m_data, t.m_data, n);return !(*this == t);
}bool String::operator<(const char* s)const {if (s == nullptr) {assert(false);}size_t n = strlen(s);m_size < n ? n = m_size : n;return strncmp(m_data, s, n) < 0;
}
bool String::operator>(const char* s)const {if (s == nullptr) {assert(false);}size_t n = strlen(s);m_size < n ? n = m_size : n;return strncmp(m_data, s, n) > 0;
}
bool String::operator<=(const char* s)const{if (s == nullptr) {assert(false);}return *this < s || *this == s;
}
bool String::operator>=(const char* s)const{if (s == nullptr) {assert(false);}return *this > s || *this == s;
}
bool String::operator==(const char* s)const{if (s == nullptr) {assert(false);}size_t L = strlen(s);size_t n;m_size < L ? n = m_size : n = L;return m_size == strlen(s) && !strncmp(m_data, s, n);
}
bool String::operator!=(const char* s)const{if (s == nullptr) {assert(false);}return !(*this == s);
}bool operator<(const char* t1, const String& t2) {if (t1 == nullptr) {assert(false);}/*size_t n;size_t size = strlen(t1);size < t2.m_size ? n = size : n = t2.m_size;return strncmp(t1, t2.m_data, n) < 0;*/return t2 > t1;
}
bool operator>(const char* t1, const String& t2) {if (t1 == nullptr) {assert(false);}/*size_t n;size_t size = strlen(t1);size < t2.m_size ? n = size : n = t2.m_size;return strncmp(t1, t2.m_data, n) > 0;*/return t2 < t1;
}
bool operator<=(const char* t1, const String& t2){if (t1 == nullptr) {assert(false);}return  t2 >= t1;/*size_t n;size_t size = strlen(t1);size < t2.m_size ? n = size : n = t2.m_size;return strncmp(t1, t2.m_data, n) < 0 || size == t2.m_size && !strncmp(t1, t2.m_data, n);*/
}
bool operator>=(const char* t1, const String& t2){if (t1 == nullptr) {assert(false);}return t2 <= t1;/*size_t n;size_t size = strlen(t1);size < t2.m_size ? n = size : n = t2.m_size;return strncmp(t1, t2.m_data, n) > 0 || size == t2.m_size && !strncmp(t1, t2.m_data, n);*/
}
bool operator==(const char* t1, const String& t2){if (t1 == nullptr) {assert(false);}/*size_t n;size_t size = strlen(t1);size < t2.m_size ? n = size : n = t2.m_size;return size == t2.m_size && !strncmp(t1, t2.m_data, n);*/return t2 == t1;
}
bool operator!=(const char* t1, const String& t2){if (t1 == nullptr) {assert(false);}//return !(t1 == t2);return !(t2 == t1);
}

test.h

#pragma once
#include"string.h"
void test1();
void test2();
void test3();
void test4();
void test5();

test.cpp

#include"test.h"
void test1() {cout << "test1()\n\n";String s;s = "bcd";String s1;s1 = "abcdefghijklmn";cout << s.size() << endl;cout << s.capacity() << endl;s.resize(30, 'c');cout << s.capacity() << endl;s.empty() ? cout << "s为空\n" : cout << "s不为空\n";cout << s1.find('c') << endl;cout << s1.find("nop") << endl;cout << s1.find(s) << endl;cout << s << endl;s.clear();s.empty() ? cout << "s为空\n" : cout << "s不为空\n";cout << s << endl;system("pause");system("cls");
}
void test2() {cout << "test2()\n\n";String s;s = "bcd";String s1;s1 = "abcdefghijklmn";String s2("rst");String s3(s2);String s4(5, 'z');cout << "s: " << s << endl;cout << "s1: " << s1 << endl;cout << "s2 :" << s2 << endl;cout << "s3 :" << s3 << endl;cout << "s4 :" << s4 << endl;s1 += 'o';cout << "s1: " << s1 << endl;s1 += "pq";cout << "s1: " << s1 << endl;s1 += s2;cout << "s1: " << s1 << endl;s1 = "字母" + s1;cout << "s1: " << s1 << endl;s1 = s1 + "uv";cout << "s1: " << s1 << endl;String s5 = "wx";s1 = s1 + s5;cout << "s1: " << s1 << endl;const char* c_s = s1.c_str();cout << "c_S: ";for (size_t i = 0; i < s1.size(); ++i) {cout << c_s[i];}cout << endl;String::Iterator begin = s1.begin();String::Iterator  end = s1.end();String s6(s1.begin(), s1.end());String s8;s8.append(s2.begin(), s2.end());cout << "s6: " << s6 << endl;cout << "s8: " << s8 << endl;system("pause");system("cls");
}
void test3() {cout << "test3()\n\n";String s1;s1 = "abcdefghijklmn";const char* c_s2 = "lmn";const char* c_s3 = "abcf";const char* c_s4 = "ghi";String s2(c_s2);String s3(c_s3);String s4(c_s4);cout << "s1 :" << s1 << endl;cout << "s2 :" << s2 << endl;cout << "s3 :" << s3 << endl;cout << "s4 :" << s4 << endl;cout << "c_s2 :" << c_s2 << endl;cout << "c_s3 :" << c_s3 << endl;cout << "c_s4 :" << c_s4 << endl;char c1 = 'd';char c2 = 'z';cout << s1.find(c1) << endl;cout << s1.find(c2) << endl;cout << s1.find(c_s2) << endl;cout << s1.find(c_s3) << endl;cout << s1.find(c_s4) << endl;cout << s1.find(s2) << endl;cout << s1.find(s3) << endl;cout << s1.find(s4) << endl;cout << s1.rfind(s2, s1.size()) << endl;cout << s1.rfind(s3, s1.size()) << endl;cout << s1.rfind(s4, s1.size()) << endl;cout << s1.substr(10, 10) << endl;String s10;s10 = "123456789";cout << s10.substr(3, 7) << endl;cout << s10.substr(10, 7) << endl;system("pause");system("cls");
}
void test4() {cout << "test4()\n\n";String s1 = "abcde";String s2 = "abc";String s3 = "cde";String s4(s1);cout << "s1: " << s1 << endl;cout << "s2: " << s2 << endl;cout << "s3: " << s3 << endl;cout << "s4: " << s4 << endl;s1 < s2 ? cout << "s1<s2\n" : cout << "s1>=s2\n";s3 > s2 ? cout << "s3>s2\n" : cout << "s3<=s2\n";s1 <= s2 ? cout << "s1<=s2\n" : cout << "s1>s2\n";s3 >= s2 ? cout << "s3>=s2\n" : cout << "s3<s2\n";s1 == s4 ? cout << "s1==s4\n" : cout << "s1!=s4\n";s1 != s2 ? cout << "s1!=s2\n" : cout << "s1==s2\n";const char* c_s1 = s1.c_str();const char* c_s2 = s2.c_str();const char* c_s3 = s3.c_str();const char* c_s4 = s4.c_str();cout << "c_s1: " << c_s1 << endl;cout << "c_s2: " << c_s2 << endl;cout << "c_s3: " << c_s3 << endl;cout << "c_s4: " << c_s4 << endl;s1 < c_s2 ? cout << "s1<c_s2\n" : cout << "s1>=c_s2\n";s3 > c_s2 ? cout << "s3>c_s2\n" : cout << "s3<=c_s2\n";s1 <= c_s2 ? cout << "s1<=s2\n" : cout << "s1>s2\n";s3 >= c_s2 ? cout << "s3>=s2\n" : cout << "s3<s2\n";s1 == c_s4 ? cout << "s1==c_s4\n" : cout << "s1!=c_s4\n";s1 != c_s2 ? cout << "s1!=c_s2\n" : cout << "s1==c_s2\n";cout << "\n\n\n";c_s2 > s1 ? cout << " c_s2>s1\n" : cout << "c_s2<=s1\n";c_s2 < s3 ? cout << " c_s2<s3\n" : cout << "c_s2>=s3\n";c_s2 >= s1 ? cout << "c_s2>=s1\n" : cout << "c_s2<s1\n";c_s2 <= s3 ? cout << "c_s2<=s3\n" : cout << "c_s2>s3\n";c_s4 == s1 ? cout << "c_s4==s1\n" : cout << "c_s4!=s1\n";c_s2 != s1 ? cout << "c_s2!=s1\n" : cout << "c_s2==s1\n";system("pause");system("cls");
}
void test5() {cout << "test5()\n\n";String s1;cout << "请输入s1\n";cin >> s1;cout << "s1: " << s1 << endl;String s2;cout << "请输入s2\n";getline(cin, s2);cout << "s2: " << s2 << endl;cout << "请输入s2, #结束\n";getline(cin, s2, '#');cout << "s2: " << s2 << endl;system("pause");system("cls");
}

main.cpp

#include"string.h"
#include"test.h"
int main() {test1();test2();test3();test4();test5();return 0;
}

C++ string类和常用接口的实现相关推荐

  1. 【C++要笑着学】编码的由来 | basic_string模板类 | string类的常用接口讲解 | 学会查文档

      ​​​​​​ 

  2. 004_JDK的String类对Comparable接口的实现

    1. JDK1.8中String类对Comparable接口的实现 2. String类对Comparable接口的实现, 首先比较的是两个字符串中每个字符的Unicode码的值, 其次比较的是两个字 ...

  3. 17.Java常用实用类之String类中常用的方法以及一般应用场景,final关键字

    文章目录 1.String类学习 1.1.什么是String类 1.2.String类中常用的方法 1.2.1. 构造方法 1.2.2.public int length() 1.2.3.public ...

  4. string类的常用函数

    string类的构造函数: string(const char *s); //用c字符串s初始化 string(int n,char c); //用n个字符c初始化 此外,string类还支持默认构造 ...

  5. string类的常用函数(总结)

    string类常用成员函数 (1)求长度 int length(); int size(); //求长度 (2)比较2个字符串 strcmp(s1,s2) == 0 直接用运算符 < > ...

  6. String类的常用AP1

    public static void main(String[] args) {//0 123456789012345String str = "thinking in java" ...

  7. String类中常用的方法

    https://blog.csdn.net/lz_1014/article/details/86241850

  8. 内存分布malloc/calloc/realloc/free/new/delete、内存泄露、String模板、浅拷贝与深拷贝以及模拟string类的实现

    内存分布 一.C语言中的动态内存管理方式:malloc/calloc/realloc和free 1.malloc: 从堆上获得指定字节的内存空间,函数声明:void *malloc (int n); ...

  9. C++【STL】【string类的使用】

    目录 string类的常用接口说明 1. string类对象的常见构造 2. string类对象的容量操作 3. string类对象的访问及遍历操作 [LeetCode]反转字符串 string的迭代 ...

最新文章

  1. php编写星期几,PHP实现今天是星期几的几种写法
  2. HTML-参考手册: URL 编码
  3. android 许可协议,Android 基本控件的使用二(注册许可协议)(CheckBox)
  4. 飞飞php2.8采集失败_飞飞影视系统火车头采集器采集发布免登录接口
  5. 2019年java安装步骤_win10的JAVA(jdk)2020年最新版安装教程心得
  6. 2021年的Angular最佳实践
  7. 从零开始学ios开发(十四):Navigation Controllers and Table Views(上)
  8. 内存模拟块设备驱动程序设计
  9. Linq的Distinct太不给力了
  10. php 同义词词库,php实现seo伪原创,同义词替换 | 学步园
  11. windbg内核诊断方式--转载
  12. TARA-基于J3061的概念阶段流程
  13. 杭州电子科技大学acm--2018
  14. ARM嵌入式实验 熟悉PROTEUS电子仿真软件的使用(LPC2138)
  15. 【大数据安全分析】图计算在安全方面的应用思考
  16. Convert UOM values
  17. 【uniapp | 微信小程序】注册和开发环境搭建
  18. 在Win10下安装Anaconda3,“开始”菜单目录下只有Anconda prompt怎么办
  19. win10——microsoft同步用户主题桌面背景的本地位置、默认背景位置、双屏双背景图设置
  20. SpringBoot发送html邮箱验证码

热门文章

  1. 大数据开发就业:大数据开发有哪些岗位
  2. 给宝宝用乳糖酶还在不停地换品牌吗?一文读懂如何正确使用
  3. 访问国内网站提示无法访问
  4. 大智慧专业财务数据服务器文件,大智慧专业财务数据及代码内容对照表-2
  5. mysql 8.0.11-winx64_mysql-8.0.11-winx64 安装步骤
  6. 企业品牌私域化运营,私域流量只是起步
  7. 初识CMake,如何编写一个CMake工程(下)
  8. 基于 abp vNext 和 .NET Core 开发博客项目 - 接入GitHub,用JWT保护你的API
  9. 卡券优惠接口对接开发源码
  10. 板绘都有哪些优缺点?应该注意什么