对C++中string类型的总结

2023-01-08,

简化构造函数原型如下(注意,为了简便,把模板中最后一个默认参数省略了):

1:  explicit basic_string();
2:  string(const char *s);
3:  string(const char *s, size_type n);
4:  string(const string& str);
5:  string(const string& str, size_type pos, size_type n);
6:  string(size_type n, E c);
7:  string(const_iterator first, const_iterator last);

.codearea { color: rgba(0, 0, 0, 1); background-color: rgba(255, 255, 255, 1); line-height: 18px; border: 1px solid rgba(79, 129, 189, 1); margin: 0; width: 100%; overflow: auto; text-align: left; font-size: 12px; font-family: "Courier New", "Consolas", "Fixedsys", "BitStream Vera Sans Mono", courier, monospace, serif }
.codearea pre { color: rgba(0, 0, 0, 1); line-height: 18px; padding: 0 0 0 12px !important; margin: 0; background-color: rgba(255, 255, 255, 1) !important }
.linewrap pre { white-space: ; word-wrap: break-word; word-break: normal }
.codearea pre.alt { background-color: rgba(247, 247, 255, 1) !important }
.codearea .lnum { color: rgba(79, 129, 189, 1); line-height: 18px }

string对象的操作

  1. 字符串比较

            支持六种关系运算符(==、!=、>、>=、<、<=),其采用字典排序策略(与C中字符串比较策略完全一样)。这六个关系运算符是非成员的重载运算符。而这些运算符都支持三种操作数组合:string op string、string op const char*、const char* op string(其中op是前面六种关系运算符中任意一种)。解释:提供运算符的三种重载版本主要是从效率角度考虑的,其避免了临时string对象的产生。

            另外,string类还提供了各种重载版本的成员函数compare来比较,简化函数原型为:

    1:  int compare(const string& str) const;
    2:  int compare(size_type p0, size_type n0, const string& str);
    3:  int compare(size_type p0, size_type n0, const string& str, size_type pos, size_type n);
    4:  int compare(const char* s) const;
    5:  int compare(size_type p0, size_type n0, const char* s) const;
    6:  int compare(size_type p0, size_type n0, const char* s, size_type n) const;

                 返回值:如果调用该函数的对象的比较序列小于操作数比较序列,则返回负数;若相等,则返回0;否则,返回正数。
    .codearea { color: rgba(0, 0, 0, 1); background-color: rgba(255, 255, 255, 1); line-height: 18px; border: 1px solid rgba(79, 129, 189, 1); margin: 0; width: 100%; overflow: auto; text-align: left; font-size: 12px; font-family: "Courier New", "Consolas", "Fixedsys", "BitStream Vera Sans Mono", courier, monospace, serif }
    .codearea pre { color: rgba(0, 0, 0, 1); line-height: 18px; padding: 0 0 0 12px !important; margin: 0; background-color: rgba(255, 255, 255, 1) !important }
    .linewrap pre { white-space: ; word-wrap: break-word; word-break: normal }
    .codearea pre.alt { background-color: rgba(247, 247, 255, 1) !important }
    .codearea .lnum { color: rgba(79, 129, 189, 1); line-height: 18px }

     

  2. 字符串相加
           

            针对string类提供了非成员重载operator+,支持string对象之间、string对象与const char*对象之间、string对象与char对象之间相加,并且operator + 两边的操作数的任意顺序都支持。简化函数原型如下:
           

    1:  string operator+ (const string& lhs, const string& rhs);
    2:  string operator+ (const string& lhs, const char *rhs);
    3:  string operator+ (const string& lhs, char rhs);
    4:  string operator+ (const char *lhs, const string& rhs);
    5:  string operator+ (char lhs, const string& rhs);

     

  3. 字符串赋值
           

            字符串赋值有两种方式:一是利用成员重载运算符operator=;另外就是使用成员重载函数assign可以更加灵活地处理。这里只提供简化函数原型供参考:

    1:  string& operator=(char c);
    2:  string& operator=(const char *s);
    3:  string& operator=(const string& rhs);
    4:  string& assign(const char *s);
    5:  string& assign(const char *s, size_type n);
    6:  string& assign(const string& str, size_type pos, size_type n);
    7:  string& assign(const string& str);
    8:  string& assign(size_type n, char c);
    9:  string& assign(const_iterator first, const_iterator last);

     

  4. 字符串追加

            字符串追加同样有两种方式:一是operator+=;另外就是成员函数append。简化函数原型如下:

    1:  string& operator+=(char c);
    2:  string& operator+=(const char *s);
    3:  string& operator+=(const string& rhs);
    4:  string& append(const char *s);
    5:  string& append(const char *s, size_type n);
    6:  string& append(const string& str, size_type pos, size_type n);
    7:  string& append(const string& str);
    8:  string& append(size_type n, char c);
    9:  string& append(const_iterator first, const_iterator last);

     

  5. 读取子串

            获取某个下标处的字符:一是用at成员函数;另外就是用operator[]。获取子串,可以用成员函数c_str及substr,还有成员函数data和copy。简化函数原型如下:

    1:  reference operator[](size_type pos);
    2:  const_reference operator[](size_type pos) const;
    3:  reference at(size_type pos);
    4:  const_reference at(size_type pos) const;
    5:   
    6:  const char *c_str() const;
    7:  const char *data() const;
    8:  string substr(size_type pos = 0, size_type n = npos) const;
    9:  size_type copy(char *s, size_type n, size_type pos = 0) const;

            注意:若at函数的参数pos无效,则抛出异常out_of_range;但如果operator[]的参数pos无效,则属于未定义行为。所以at比operator[]更加安全。

            其中,copy返回实际拷贝的字符数。

  6. 替换子串

            成员函数replace实现替换某个子串。简化函数原型如下:

     1:  string& replace(size_type p0, size_type n0, const char *s);
     2:  string& replace(size_type p0, size_type n0, const char *s, size_type n);
     3:  string& replace(size_type p0, size_type n0, const string& str);
     4:  string& replace(size_type p0, size_type n0, const string& str, size_type pos, size_type n);
     5:  string& replace(size_type p0, size_type n0, size_type n, char c);
     6:  string& replace(iterator first0, iterator last0, const char *s);
     7:  string& replace(iterator first0, iterator last0, const char *s, size_type n);
     8:  string& replace(iterator first0, iterator last0, const string& str);
     9:  string& replace(iterator first0, iterator last0, size_type n, char c);
    10:  string& replace(iterator first0, iterator last0, const_iterator first, const_iterator last);

             这里,可能需要用到这几个函数得到整个字符序列:

    1:  const_iterator begin() const;
    2:  iterator begin();
    3:  const_iterator end() const;
    4:  iterator end();

     

  7. 插入字符串

            成员函数insert实现在某点处插入字符串。简化函数原型如下:

    1:  string& insert(size_type p0, const char *s);
    2:  string& insert(size_type p0, const char *s, size_type n);
    3:  string& insert(size_type p0, const string& str);
    4:  string& insert(size_type p0, const string& str, size_type pos, size_type n);
    5:  string& insert(size_type p0, size_type n, char c);
    6:  iterator insert(iterator it, char c);
    7:  void insert(iterator it, const_iterator first, const_iterator last);
    8:  void insert(iterator it, size_type n, char c);

            注意:insert函数是在插入点(p0 or it)之前插入字符串。

  8. 删除子串

            成员函数 erase实现删除某个子串。简化函数原型如下:

    1:  iterator erase(iterator first, iterator last);
    2:  iterator erase(iterator it);
    3:  string& erase(size_type p0 = 0, size_type n = npos);

            如果指定删除的字符个数比字符串中从指定位置开始的剩余字符个数还多,那么只有这些字符被删除。

  9. 查找子串

            查找子串有六种方式,分别有五类成员函数与之应。

                    · find 查找控制字符序列中与操作字符序列匹配的第一个子串,并返回子串的起始位置;

                    · rfind 查找控制字符序列中与操作字符序列匹配的最后一个子串,并返回该子串的起始位置,相当于逆向查找;

                    · find_first_of 查找控制字符序列中第一个出现在操作字符序列中的字符的位置,并返回该位置;

                    · find_first_not_of查找控制字符序列中第一个不出现在操作字符序列中的字符的位置,并返回该位置;

                    · find_last_of 查找控制字符序列中最后一个出现在操作序列中的字符的位置,并返回该位置;

                    · find_last_not_of 查找控制字符序列中最后一个不出现在操作字符序列中的字符位置,并返回该位置;

             如果这些函数查找失败,则返回string::npos。

             其中,find函数的简化函数原型如下:

    1:  size_type find(char c, size_type pos = 0) const;
    2:  size_type find(const char *s, size_type pos = 0) const;
    3:  size_type find(const char *s, size_type pos, size_type n) const;
    4:  size_type find(const string& str, size_type pos = 0) const;

            另外的五个函数的函数原型和find的函数原型类型类似,区别在于,如果是是逆序查找的函数(rfind, find_last_of, find_last_not_of),则pos参数默认值为npos。

  10. 其它成员函数和友元函数

     1:  size_type capacity() const;   // 返回当前字符串的存储空间大小>=size()
     2:  void reserve(size_type n = 0);// 预留n个元素的存储空间,保证capacity()>=n
     3:  bool empty() const;           // 若字符串为空,返回true
     4:  size_type size() const;       // 返回字符串长?
     5:  size_type length() const;     // 等于size()
     6:  size_type max_size() const;   //返回string类中字符串的最大长度
     7:  void resize(size_type n, char c = ' '); //若长度不够,则用c填充加长的部分;保证size()返回n
     8:  void swap(string& str);      //两string对象交换,能在常数时间内完成(必须是使用相同allocator的两对象,这里都使用的默认的)
     9:  
    10:  // 其它非成员函数
    11:  istream& getline(istream& is, string& str);
    12:  istream& getline(istream& is, string& str, char delim);
    13:  ostream& operator<<(ostream& os, const string& str);
    14:  istream& operator>>(istream& is, const string& str);

            其中,istream& getline(istream& is, string& str); 相当于 istream& getline(istream& is, string& str, char delim = '\n');

            getline函数在下列三种情况下结束提取:

                    1)遇到文件结束符;

                    2)遇到分隔符delim。如果第一个就是分隔符,str为空串(并且该分隔符被从流中读出丢弃),但istream测试为真;

                    3)如果已经提取了istream.max_size()个字符,那么提取结束,并且将调用istream.setstate(ios_base::failbit),即此时返回的istream测试为假。

            如果函数没有提取到字符(包括分隔符),那么将调用istream.setstate(failbit),此时测试istream为假。

            默认情况下, istream& operator>>(istream& is, const string& str);在下列三种情况下结束提取:
                    1)遇到文件结束符;
                    2)遇到空白字符(空格、Tab、换行);
                    3)如果已经提取了is.max_size()个字符,或者提取了is.width()(非0情况下)个字符。
            如果没有提取到任何非文件结束符的字符(包括空白字符),那么将调用istream.setstate(failbit),此时测试istream为假。

            例如,看看下面的循环:

    1:  while(cin >> word) 
    2:  { 
    3:      cout << "word read is: " << word << '\n'; 
    4:  }

     

            要中止上面的循环应该用文件结束符: 
                    Win——Ctrl+Z              Unix——Ctrl+D
            并且,应该是输入行的第一个字符就是文件结束符,然后回车才能结束循环。