0


【STL详解】string类


1.标准库中的string类

总结:
1.) string是表示字符串的字符串类。
2. )该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。

  1. )string在底层实际是:basic_string模板类的别名,typedef basic_string<char,char_traits, allocator>string;
  2. )不能操作多字节或者变长字符的序列。

string类的常用接口说明:

1. string类对象的常见构造

(constructor)*函数名称 功能说明string() (重点)构造空的string类对象,即空字符串string(const char s) (重点)用C-string来构造string类对象string(size_t n, char c) string类对象中包含n个字符cstring(const string&s) (重点) **拷贝构造函数

string();  //构造一个空字符串

string(const char* s);  //复制s所指的字符序列

string(const char* s, size_t n);  //复制s所指字符序列的前n个字符

string(size_t n, char c);  //生成n个c字符的字符串

string(const string& str);  //生成str的复制品

string(const string& str, size_t pos, size_t len = npos);  //复制str中从字符位置pos开始并跨越len个字符的部分

使用示例:

string s1;                     //构造空字符串
string s2("hello");            //复制"hello string"
string s3("hello", 3);         //复制"hello string"的前3个字符
string s4(10, 's');            //生成10个's'字符的字符串
string s5(s2);                 //生成s2的复制品
string s6(s2, 1, 4);           //复制s2中从字符位置1开始并跨越4个字符的部分

2.2string类对象的容量操作

*函数名称 功能说明size返回字符串有效字符长度length返回字符串有效字符长度capacity返回空间总大小empty检测字符串释放为空串,是返回true,否则返回falseclear清空有效字符reserve为字符串预留空间resize*将有效字符的个数该成n个,多出的空间用字符c填充
使用示例:

1、使用size函数或length函数获取当前有效字符的个数

size_t size() const;
size_t length() const;

    string s("CSDN");
    cout << s.size() << endl; //4
    cout << s.length() << endl; //4

2、 使用capacity函数获取当前对象所分配的存储空间的大小

size_t capacity() const;

    string s("CSDN");
    cout << s.capacity() << endl; //15

3、使用resize改变当前对象的有效字符的个数

void resize (size_t n);
void resize (size_t n, char c);

resize规则:
 1、当n大于对象当前的size时,将size扩大到n,扩大的字符为c,若c未给出,则默认为’\0’。
 2、当n小于对象当前的size时,将size缩小到n。

使用实例:

    string s1("ABCD");
    //resize(n)n大于对象当前的size时,将size扩大到n,扩大的字符默认为'\0'
    s1.resize(20);
    cout << s1 << endl; //ABCD
    cout << s1.size() << endl; //20
    cout << s1.capacity() << endl; //31

    string s2("ABCD");
    //resize(n, char)n大于对象当前的size时,将size扩大到n,扩大的字符为char
    s2.resize(20, 'x');
    cout << s2 << endl; //ABCDxxxxxxxxxxxxxxxx
    cout << s2.size() << endl; //20
    cout << s2.capacity() << endl; //31

    string s3("ABCD");
    //resize(n)n小于对象当前的size时,将size缩小到n
    s3.resize(2);
    cout << s3 << endl; //AB
    cout << s3.size() << endl; //2
    cout << s3.capacity() << endl; //15

** 注意**:若给出的n大于对象当前的capacity,则capacity也会根据自己的增长规则进行扩大。

4、使用reserve改变当前对象的容量大小

void reserve (size_t n = 0);

reserve规则:
 1、当n大于对象当前的capacity时,将capacity扩大到n或大于n。
 2、当n小于对象当前的capacity时,什么也不做。

使用示例:

    string s("ABCD");
    cout << s << endl; //ABCD
    cout << s.size() << endl; //4
    cout << s.capacity() << endl; //15

    //reverse(n)当n大于对象当前的capacity时,将当前对象的capacity扩大为n或大于n
    s.reserve(20);
    cout << s << endl; //ABCD
    cout << s.size() << endl; //4
    cout << s.capacity() << endl; //31

    //reverse(n)当n小于对象当前的capacity时,什么也不做
    s.reserve(2);
    cout << s << endl; //ABCD
    cout << s.size() << endl; //4
    cout << s.capacity() << endl; //31

** 注意**:此函数对字符串的size没有影响,并且无法更改其内容。

以上小结:

  1. )size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。

  2. )clear()只是将string中有效字符清空,不改变底层空间大小。

3.) resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。 注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

  1. )reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。

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

函数名称功能说明operator[] 返回pos位置的字符,const string类对象调用begin获取第一个字符的迭代器end获取最后一个字符下一个位置的迭代器rbegin返回指向字符串最后一个字符的‎‎反向迭代器‎rend‎返回指向字符串第一个字符前面的理论元素的‎‎反向迭代器‎**范围for**C++11支持更简洁的范围for的新遍历方式
1、[ ]+下标
 因为string类对[ ]运算符进行了重载,所以我们可以直接使用[ ]+下标访问对象中的元素。并且该重载使用的是引用返回,所以我们可以通过[ ]+下标修改对应位置的元素。

char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;

    string s("ABCD");
    //[]+下标访问对象元素
    for (size_t i = 0; i < s.size(); i++)
    {
        cout << s[i];
    }
    cout << endl;

    //[]+下标修改对象元素内容
    for (size_t i = 0; i < s.size(); i++)
    {
        s[i] = 'a';
    }
    cout << s << endl; //aaaa

2、使用迭代器访问对象中的元素

    iterator begin();
 const_iterator begin() const;
    iterator end();
 const_iterator end() const;
    reverse_iterator rbegin();
 const_reverse_iterator rbegin() const;
    reverse_iterator rend();
 const_reverse_iterator rend() const;

    string s("ABCD");

    //使用迭代器访问对象元素
    string::iterator it1 = s.begin();
    while (it1 != s.end())
    {
        cout << *it1;
        it1++;
    }
    cout << endl; //ABCD

    //使用迭代器访问对象元素,并对其进行修改
    string::iterator it2 = s.begin();
    while (it2 != s.end())
    {
        *it2 += 1;
        it2++;
    }
    cout << s << endl; //DCBA

3、使用范围for访问对象中的元素
 需要注意的是:若是需要通过范围for修改对象的元素,则用于接收元素的变量e的类型必须是引用类型,否则e只是对象元素的拷贝,对e的修改不会影响到对象的元素。

    string s("ABCD");
    //使用范围for访问对象元素
    for (auto e : s)
    {
        cout << e;
    }
    cout << endl; //CSDN

    //使用范围for访问对象元素,并对其进行修改
    for (auto& e : s) //需要修改对象的元素,e必须是引用类型
    {
        e = 'x';
    }
    cout << s << endl; //xxxx

4. string类对象的修改操作

*函数名称 功能说明push_back在字符串后尾插字符cappend在字符串后追加一个字符串operator+=在字符串后追加字符串strc_str返回C格式字符串find + npos从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置rfind从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置substr*在str中从pos位置开始,截取n个字符,然后将其返回
使用实例:

#include <iostream>
#include <string>
using namespace std;

void Teststring()
{
    string str;
    str.push_back(' ');            // 在str后插入空格
    str.append("hello");        // 在str后追加一个字符"hello"
    str += 'l';                    // 在str后追加一个字符'l'
    str += "xy";                // 在str后追加一个字符串"xy"
    cout << str << endl;        //  hellolxy
    cout << str.c_str() << endl; // 以C语言的方式打印字符串

    // 获取file的后缀
    string file("string.cpp");
    size_t pos = file.rfind('.');
    string suffix(file.substr(pos, file.size() - pos));
    cout << suffix << endl; //cpp
    // npos是string里面的一个静态成员变量
    // static const size_t npos = -1;
    // 取出url中的域名
    string url("http://www.cplusplus.com/reference/string/string/find/");
    cout << url << endl;
    size_t start = url.find("://");
    if (start == string::npos)
    {
        cout << "invalid url" << endl;
        return;
    }
    start += 3; // 指向W
    size_t finish = url.find('/', start); //从start向后开始找'/'
    string address = url.substr(start, finish - start);
    cout << address << endl; //www.cplusplus.com
    // 删除url的协议前缀
    pos = url.find("://");
    url.erase(0, pos + 3);
    cout << url << endl; //www.cplusplus.com/reference/string/string/find/
}

int main()
{
    Teststring();
    return 0;
}

1、使用c_str或data将string转换为字符串

const char* c_str() const;
const char* data() const;

区别:

  • 在C++98中,c_str()返回 const char* 类型,返回的字符串会以空字符结尾。
  • 在C++98中,data()返回 const char* 类型,返回的字符串不以空字符结尾。
  • 但是在C++11版本中,c_str()与data()用法相同。
    string s("hello world ");
    const char* str1 = s.data();
    const char* str2 = s.c_str();

    cout << str1 << endl;
    cout << str2 << endl;

2、使用substr函数提取string中的子字符串

string substr (size_t pos = 0, size_t len = npos) const;

    string s1("abcdef");
    string s2;

    //substr(pos, n)提取pos位置开始的n个字符序列作为返回值
    s2 = s1.substr(2, 3);
    cout << s2 << endl; //cde

注意:
1. )在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
2. )对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。

5. string类非成员函数

*函数功能说明operator+尽量少用,因为传值返回,导致深拷贝效率低operator>>输入运算符重载operator<<输出运算符重载getline获取一行字符串relational operators*大小比较
1、operator+

string类中对+运算符进行了重载,重载后的+运算符支持以下几种类型的操作:
  1.)string类 + string类
  2.)string类 + 字符串
  3.)字符串 + string类
  4.)string类 + 字符
  5.)字符 + string类
它们相加后均返回一个string类对象。

2、operator>> 和 operator<<

string类中也对>>和<<运算符进行了重载,这就是为什么我们可以直接使用>>和<<对string类进行输入和输出的原因。

3、relational operators

    string类中还对一系列关系运算符进行了重载,它们分别是==、!=、<、<=、>、>=。重载后的关系运算符支持string类和string类之间的关系比较、string类和字符串之间的关系比较、字符串和string类之间的关系比较。

4、getline函数

1.)istream& getline (istream& is, string& str);

getline函数将从is中提取到的字符存储到str中,直到读取到换行符’\n’为止。

string s;
getline(cin, s); //输入:hello lxy
cout << s << endl; //输出:hello lxy

2.) istream& getline (istream& is, string& str, char delim);

getline函数将从is中提取到的字符存储到str中,直到读取到分隔符delim或换行符’\n’为止。

string s;
getline(cin, s, 'x'); //输入:hello lxy
cout << s << endl; //输出:hello l
标签: c++

本文转载自: https://blog.csdn.net/m0_51866180/article/details/123762279
版权归原作者 Soryu_Shikinami 所有, 如有侵权,请联系我们删除。

“【STL详解】string类”的评论:

还没有评论