STLstring

mac2026-08-10  7

目录

一、为什么会出现string 类?

二、 string类

三、常用的接口说明


 

一、为什么会出现string 类?

c++中string是标准模板库中仅少的不需要传类型。

在c语言中,操作字符串是针对内存操作的,字符串是用字符数组表示的,在实际情况中,我们会经常用到字符串,那么继续使用字符数组就会显得及其不方便,所以在c++标准库中就通过类string重新自定义字符串。

二、 string类

1、string是表示字符串的字符串类

2、该类的接口与常规容器的接口基本相同,在此基础上添加了一些专门用来操作string的常规操作。

3、string在底层实际是:basic_string模板类的别名。typedef basic_string<char,char_traits,allocator>string;

4、不能操作多字节或变长字符的序列。

三、常用的接口说明

 1、string 常用的构造函数

string()

构造空的string类对象,即空的字符串

string (const char * s)

用c-string来构造string类对象

string (size_t,char c)

string类对象包含n个c字符

string (const string &s)

拷贝构造函数

 

 

 

 

 

string s; //构造空的字符串s string s("ABC"); // 构造字符串s,内容是"ABC" string s(5, 'c'); // 存储5个c到s中

 2、string 类的容量操作

size()返回字符串的有效长度length()返回字符串的有效长度capacity()返回空间总大小empty()检测字符串是否为空串,是返回true 不是返回falseclear()

清空有效字符

reserve()为字符串预留有效空间resize()

将有效字符串个数改成n个,多出的空间用c填充

class String { char * m_data; size_t m_size; size_t m_capacity; public: String(const char * str = "") : //默认构造函数 m_capacity(DEFAULTCAPA) { if (nullptr == str) { str = "";//str可以换指向,因为const没有修饰指针,若修饰指针为char * const str } m_size = strlen(str); m_capacity = COUNTCAPA(m_size); m_data = new char[m_capacity]; strncpy(m_data, str, m_size); } String(String &s)//传引用 ,防止无限递归 拷贝构造 执行深拷贝 //写时执行深拷贝,读时执行浅拷贝 { m_size = s.m_size; m_capacity = s.m_capacity; m_data = new char[m_capacity];//一般执行深拷贝,需要重新开辟空间 strcpy(m_data, s.m_data); } String & operator = (const char * str) { m_size = strlen(str); reserve(m_size); strcpy(m_data, str); return *this; } String & operator = (String &s) { m_size = s.m_size; reserve(m_size); strcpy(m_data, s.m_data); return *this; } String(size_t n, char ch) : //n个字符串的构造 m_size(n), m_capacity(COUNTCAPA(n)) { //reserve(m_size); m_data = new char[m_capacity]; memset(m_data, ch, m_size); } ~String() { if (m_data)//避免重复释放 { delete[]m_data; m_data = NULL; } m_size = m_capacity = 0; } size_t size()//返回字符串有效字符长度 { return m_size; } size_t length() //返回字符串有效字符长度 { return m_size; } size_t capacity() //返回空间总大小 { return m_capacity - 1; } bool empty() //检测字符串释放为空串,是返回true,否则返回false { return m_size == 0; } void clear() //清空有效字符 { m_size = 0; } void reserve(size_t size) { if (size >= m_capacity) { m_capacity = COUNTCAPA(m_size); m_data = (char*)realloc(m_data, m_capacity); } } void resize(size_t size,char ch = '\0') //将有效字符的个数改成n个,多出的空间用字符c填充 { reserve(size); if (m_size < size) { memset(m_data + m_size, ch, size - m_size);//将重新申请的出来的多出来的空间赋为ch } m_size = size; } }

测试函数

int main() { String s(4, 'n'); cout << s << endl; cout << s.size() << endl; cout << s.length() << endl; cout << s.capacity() << endl; cout << s.empty() << endl; s.reserve(6); cout << s << endl; cout << s.size() << endl; cout << s.length() << endl; cout << s.capacity() << endl; cout << s.empty() << endl; s.resize(12, 'c'); cout << s << endl; cout << s.size() << endl; cout << s.length() << endl; cout << s.capacity() << endl; cout << s.empty() << endl; s.clear(); cout << s << endl; cout << s.size() << endl; cout << s.length() << endl; cout << s.capacity() << endl; cout << s.empty() << endl; system("pause"); return 0; }

注意:

  size()与length()方法底层实现原理完全相同。clear()只是将String中有效字符清空,不改变底层空间的大小。resize()参数为2个,如果只有一个参数的话,系统默认另一个参数为字符0,resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减小,底层空间大小不变。reserve: 为string预留空间,不改变有效元素个数,当reserve 的参数小于string的底层空间总大小时,reserve 不会改变容量大小。

3、 string类对象的访问及遍历操作

operator[]返回pos位置的字符,const string类对象调用begin+end正向迭代器,begin取第一个字符,end取最后一个字符的下一个位置rbegin+rend反向迭代器,与上边相反范围for  #include <iostream> #include <string> using namespace std; int main() { string s("hello"); for (size_t i = 0; i < s.size(); ++i) { cout << s[i] << ' '; } cout << endl; string::iterator it = s.begin(); while (it != s.end()) { cout << *it << ' '; ++it; } cout << endl; string::reverse_iterator it1 = s.rbegin(); while (it1 != s.rend()) { cout << *it1 << ' '; ++it1; } cout << endl; for (auto ch : s) { cout << ch << ' '; } system("pause"); return 0; }

4、string类对象的修改操作

push_back

在字符串后尾插字符cappend

在字符串后追加个字符串

operator+=在字符串后追加字符串strc_st返回C格式字符串fifind + npos从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置rfifind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置substrstr中从pos位置开始,截取n个字符,然后将其返回 class String { char * m_data; size_t m_size; size_t m_capacity; public: void push_back(char ch) { reserve(m_size); m_data[m_size] = ch; m_size++; } void pop_back(char ch) { if (!empty()) { m_size--; } } String & operator += (const char * str) //+=的返回值一般是左值的引用 { //m_data[m_size] = '\0'; int tmp = m_size; m_size += strlen(str); reserve(m_size); strcpy(m_data + tmp, str); return *this; } String & operator += (String &s) { //m_data[m_size] = '\0';//strcat 遇到尾0才能进行加 int tmp = m_size; m_size += s.m_size; reserve(m_size); strcpy(m_data + tmp, s.m_data); return *this; } const char * c_str() { return m_data; } size_t find(char str, size_t pos = 0) { if (pos < 0 || pos >= m_size) { return -1; } char * tmp = strchr(m_data + pos, str); if (tmp) { return tmp - m_data; } else { return -1; } } size_t find(const char * str, size_t pos = 0) { if (pos < 0 || pos >= m_size) { return -1; } char * tmp = strstr(m_data + pos, str); if (tmp) { return tmp - m_data; } else { return -1; } } size_t find(const String &s, size_t pos = 0) { if (pos < 0 || pos >= m_size) { return -1; } char * tmp = strstr(m_data + pos, s.m_data); if (tmp) { return tmp - m_data; } else { return -1; } } String substr(size_t start, size_t num) { String tmp; tmp.resize(num); strncpy(tmp.m_data, m_data + start, num); return tmp; } };

测试代码:

int main() { String s("nihaoya"); s.resize(12); s.push_back('a'); cout << s << endl; cout << s.c_str() << endl; String s1("hello"); s += s1; String &ret = s; cout << ret << endl; String s3("xiao zhu pei pei pei qi"); cout << s3.find('p') <<endl; int pos = s3.find('p'); cout << s3.find('p', pos + 1) <<endl; String tmp = s3.substr(0, 5); cout << tmp; system("pause"); return 0; }

5、string类非成员函数

class String { char * m_data; size_t m_size; size_t m_capacity; public: String operator + (const char * str)const; String operator + (const String &s) const; friend String operator + (const char * str, const String &s); bool operator > (const char * str) const; bool operator < (const char * str) const; bool operator >= (const char * str) const; bool operator <= (const char * str) const; bool operator == (const char * str) const; bool operator != (const char * str) const; bool operator > (const String &s) const; bool operator < (const String &s) const; bool operator >= (const String &s) const; bool operator <= (const String &s) const; bool operator == (const String &s) const; bool operator != (const String &s) const; friend bool operator > (const char * str, const String &s); friend bool operator < (const char * str, const String &s); friend bool operator >= (const char * str, const String &s); friend bool operator <= (const char * str, const String &s); friend bool operator == (const char * str, const String &s); friend bool operator != (const char * str, const String &s); friend ostream & operator << (ostream & os, const String &s); friend istream & operator << (istream & is, String &s); }; ostream & operator << (ostream & os, const String &s) { int i; for (i = 0; i < s.m_size; i++) { os << s.m_data[i]; } return os; } istream & operator << (istream & is, String &s) { char * tmp = new char[1024]; is.getline(tmp, 1024); s.m_size = strlen(tmp); s.m_capacity = COUNTCAPA(s.m_size); strcpy(s.m_data, tmp); delete[]tmp; /*delete[]s.m_data; //比较快 s.m_data = tmp;*/ return is; } String String :: operator + (const char * str)const { String res; res.m_size = m_size + strlen(str); res.reserve(res.m_size); strncpy(res.m_data, m_data,m_size); strcpy(res.m_data + m_size, str); return res; } String String:: operator + (const String &s) const { String res; res.m_size = m_size +s.m_size; res.reserve(res.m_size); strncpy(res.m_data, m_data,m_size); strncpy(res.m_data+m_size, s.m_data,s.m_size); return res; } String operator + (const char * str, const String &s) //无this指针 为友元函数 { String res; res.m_size = strlen(str) + s.m_size; res.reserve(res.m_size); strcpy(res.m_data,str); strncat(res.m_data ,s.m_data,s.m_size); return res; } bool String:: operator > (const char * str) const { return strncmp(m_data, str, m_size) > 0; } bool String:: operator < (const char * str) const { int tmp = strncmp(m_data, str, m_size); //m_data与str前边全部相同 但str比m_data长(需要判断) if (!tmp && strlen(str) > m_size) { return true; } return tmp < 0; } bool String::operator >= (const char * str) const { return !(*this < str); } bool String::operator <= (const char * str) const { return !(*this > str); } bool String::operator == (const char * str) const { int tmp = strncmp(m_data, str, m_size); if (!tmp && strlen(str) == m_size) { return true; } return false; } bool String::operator != (const char * str) const { return !(*this == str); } bool String::operator > (const String &s) const { int i; int minsize = m_size < s.m_size ? m_size : s.m_size; for (i = 0; i < minsize; i++) { if (m_data[i] > s.m_data[i]) { return true; } else if (m_data[i] < s.m_data[i]) { return false; } } return m_size > s.m_size; } bool String::operator < (const String &s) const { int i; int minsize = m_size < s.m_size ? m_size : s.m_size; for (i = 0; i < minsize; i++) { if (m_data[i] < s.m_data[i]) { return true; } else if (m_data[i] > s.m_data[i]) { return false; } } return m_size < s.m_size; } bool String::operator >= (const String &s) const { return !(*this < s); } bool String::operator <= (const String &s) const { return !(*this > s); } bool String::operator == (const String &s) const { int i; int minsize = m_size < s.m_size ? m_size : s.m_size; for (i = 0; i < minsize; i++) { if (m_data[i] != s.m_data[i]) { return false; } } return m_size == s.m_size; } bool String::operator != (const String &s) const { return !(*this == s); } bool operator > (const char * str, const String &s) { int tmp = strncmp(str, s.m_data, s.m_size); if (!tmp && strlen(str) > s.m_size) { return true; } return tmp > 0; } bool operator < (const char * str, const String &s) { return strncmp(str, s.m_data, s.m_size) < 0; } bool operator >= (const char * str, const String &s) { return !(str < s); } bool operator <= (const char * str, const String &s) { return !(str > s); } bool operator == (const char * str, const String &s) { int tmp = strncmp(str, s.m_data, s.m_size); if (!tmp && strlen(str) == s.m_size) { return true; } return false; } bool operator != (const char * str, const String &s) { return !(str == s); }

测试代码:

int main() { String s("nihaoya"); String s1("hello"); cout << (s > s1) << endl; cout << (s < "666") << endl; cout << ("666" == s) << endl; system("pause"); return 0; }

最新回复(0)