C++学习笔记(21)——string类

string是C++标准库中表示字符串的字符串类。在之前的笔记中也涉及到过string的应用,我们大概知道string与c风格字符串的区别在于前者不用操心字符串长度的问题,其内部会动态分配需要的内存。其实string 类是 STL(标准模板库)中 basic_string 模板实例化得到的模板类。其定义如下:

typedef basic_string <char> string;

basic_string 此处可以不必深究。string 类的成员函数有很多,同一个名字的函数也常会有五六个重载的版本。篇幅所限,不能将这些原型一一列出并加以解释。这里仅对常用成员函数按功能进行分类,并直接给出应用的例子,通过例子,读者可以基本掌握这些成员函数的用法。

注意,使用string类的时候,必须包含头文件string(不是cstring或string.h)以及using namespace std。

一、构造函数

string类的构造函数如下:

string():构造空的string类对象,既空字符串

string(const char* s):使用C语言的字符串构造string类对象

string(size_t n,char c):构造后的string类对象包括n个字符c

string(const string& s):用string类对象s拷贝构造另一个对象

string(const string& s, size_t pos, size_t n):使用对象s中从pos开始的第n个字符开始构造新的string类对象

string s1; // 构造空的string类对象s1si = ""

string s2("hello,world"); //使用C字符串构造,s2 = " hello,world "

string s3(10, 'a'); // 10a构造对象,s3 = "aaaaaaaaaa"

string s4(s2); //拷贝构造,s4=”hello,world”

string s5(s2, 6, 5);//s2对象下标为的位置开始,将个字符复制到s5中,s5=”world”

二、容量操作

size_t size() const:返回字符串有效字符长度,size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。

size_t length() const:返回字符串有效的长度(同size)。

size_t capacity() const:返回空间总大小,既容量。通常,开辟的容量会比实际的大小大,且为2的整倍数。

bool empty() const:判断字符串是否为空串,是返回true,不是返回false

void clear():清空有效的字符,不改变底层空间大小。

void resize(size_t n,char c):将有效字符的个数改成n个,多出来的空间用c填充,resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。

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

    string s("hello,world");

    cout << s.length() << endl; // 11

    cout << s.size() << endl; // 11

    cout << s.capacity() << endl;// 15 ,capacity是但是实际上开辟了个char的空间,最后还有`\0`

    cout << s << endl;//string类对象支持直接用cincout进行输入输出

 

    //将对象s中的字符串清空,只改变有效数据的大小,不改变容量的大小

    s.clear();

    cout << s.size() << endl; // 0

    cout << s.capacity() << endl; // 15

 

    // s中有效字符个数增加到个,多出位置用'j'进行填充

    s.resize(10, 'j');

    cout << s.size() << endl; // 10

    cout << s.capacity() << endl; // 15

    cout << s << endl; // jjjjjjjjjj

 

    //s中有效字符个数增加到个,多出位置用缺省值'\0'进行填充

    s.resize(15);

    cout << s.size() << endl; // 15

    cout << s.capacity() << endl; // 15

    cout << s << endl; // jjjjjjjjjj\0\0\0\0\0

 

    //s中有效字符个数缩小到个

    s.resize(5);

    cout << s.size() << endl; // 5

    cout << s.capacity() << endl; // 15

    cout << s << endl; // jjjjj

    cout << "--------------" << endl;

 

    //测试reserve

    string s2("hehe");//reserve不会改变string中有效元素个数

    cout << s2.size() << endl;//4

    cout << s2.capacity() << endl;//15

    s2.reserve(100);

    cout << s2.size() << endl;//4

    cout << s2.capacity() << endl;//111

    //reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小

    s2.reserve(50);

    cout << s2.size() << endl; // 4

    cout << s2.capacity() << endl; // 111

三、访问操作

1. string类重载了[]符号获取指定元素:

char& operator[] (size_t pos):返回pos位置的字符,也可以修改

const char& operator[] (size_t pos):返回pos位置字符,只能访问不能修改

2.const char* c_str() const返回C格式的字符串,既char*

    string filename;

    cin >> filename;

    ofstream fout;

    fout.open(filename.c_str());

3.substr 成员函数可以用于求子串 (n, m),原型如下:

tring substr(int n = 0, int m = string::npos) const;

调用时,如果省略 m 或 m 超过了字符串的长度,则求出来的子串就是从下标 n 开始一直到字符串结束的部分。例如:

string s1 = "this is ok";

string s2 = s1.substr(2, 4);  // s2 = "is i"

s2 = s1.substr(2);  // s2 = "is is ok"

四、字符串连接

常见的字符串修改主要有以下接口函数:

void push_back(char c):在字符串尾插入字符c

string& append(const char* s):在字符串后边追加一个C语言字符串

string& operator+=(const string& str):在字符串后边追加string类字符串

string& operator+=(const char* s):在字符串后边追加C语言字符串

string& operator+=(char c):在字符串后追加字符c

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

除了可以使用append和+=运算符对string对象执行字符串的连接操作外,string 类还重载了+运算符,可以用来向字符串后面添加内容。

对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好,这样可以减少调用扩容函数增加的额外开销。

    string str("hello");

    str.push_back('C');//str后边追加字符C

    cout << str << endl;

    str.append(" world");//str后边追加字符串

    cout << str << endl;

    str += 'X'; //str后边追加字符X

    cout << str << endl;

    str += "xxx";//str后边追加字符串xxx

    cout << str << endl;

    cout << str.c_str() << endl;//C语言形式打印字符串

五、字符串比较

String类重载了<、<=、==、!=、>=、> 运算符比较 string 对象,同时,string 类还有 compare 成员函数,可用于比较字符串。compare 成员函数有以下返回值:

  1. 小于 0 表示当前的字符串小;

  2. 等于 0 表示两个字符串相等;

  3. 大于 0 表示另一个字符串小。

   string s1("hello"), s2("hello, world");

   int n = s1.compare(s2);

   n = s1.compare(1, 2, s2, 0, 3);  //比较s1的子串(1,2) s2的子串(0,3)

   n = s1.compare(0, 2, s2);  // 比较s1的子串(0,2) s2

   n = s1.compare("Hello");

   n = s1.compare(1, 2, "Hello");  //比较s1 的子串(1,2)"Hello”

   n = s1.compare(1, 2, "Hello", 1, 2);  //比较s1 的子串(1,2)"Hello" 的子串(1,2)

六、交换字符串

swap 成员函数可以交换两个 string 对象的内容。例如:

string s1("West"),s2("East");

s1.swap(s2);  // s1 = "East"s2 = "West"

七、查找字符或子串

string 类有一些查找子串和字符的成员函数,它们的返回值都是子串或字符在 string 对象字符串中的位置(即下标)。如果查不到,则返回 string::npos。string: :npos 是在 string 类中定义的一个静态常量。这些函数如下:

find:从前往后查找子串或字符出现的位置。

rfind:从后往前查找子串或字符出现的位置。

find_first_of:从前往后查找何处出现另一个字符串中包含的字符。例如:s1.find_first_of("abc");  //查找s1中第一次出现"abc"中任一字符的位置

find_last_of:从后往前查找何处出现另一个字符串中包含的字符。

find_first_not_of:从前往后查找何处出现另一个字符串中没有包含的字符。

find_last_not_of:从后往前查找何处出现另一个字符串中没有包含的字符。

    string s1("Source Code");

    int n;

    if ((n = s1.find('u')) != string::npos) //查找u 出现的位置

       cout << "1) " << n << "," << s1.substr(n) << endl;

    //输出l)2,urce Code

    if ((n = s1.find("Source", 3)) == string::npos)

       //从下标开始查找"Source",找不到

       cout << "2) " << "Not Found" << endl//输出2) Not Found

    if ((n = s1.find("Co")) != string::npos)

       //查找子串"Co"。能找到,返回"Co"的位置

       cout << "3) " << n << ", " << s1.substr(n) << endl;

    //输出3) 7, Code

    if ((n = s1.find_first_of("ceo")) != string::npos)

       //查找第一次出现或'c''e''o'的位置

       cout << "4) " << n << ", " << s1.substr(n) << endl;

    //输出4) l, ource Code

    if ((n = s1.find_last_of('e')) != string::npos)

       //查找最后一个'e' 的位置

       cout << "5) " << n << ", " << s1.substr(n) << endl//输出5) 10, e

    if ((n = s1.find_first_not_of("eou", 1)) != string::npos)

       //从下标开始查找第一次出现非'e''o' 'u' 字符的位置

       cout << "6) " << n << ", " << s1.substr(n) << endl;

    //输出6) 3, rce Code

八、替换字符

replace 成员函数可以对 string 对象中的子串进行替换,返回值为对象自身的引用。例如:

    string s1("Real Steel");

    s1.replace(1, 3, "123456", 2, 4);  //"123456" 的子串(2,4) 替换s1 的子串(1,3)

    cout << s1 << endl//输出R3456 Steel

    string s2("Harry Potter");

    s2.replace(2, 3, 5, '0');  //5 '0' 替换子串(2,3)

    cout << s2 << endl//输出HaOOOOO Potter

    int n = s2.find("OOOOO");  //查找子串"00000" 的位置,n=2

    s2.replace(n, 5, "XXX");  //将子串(n,5)替换为"XXX"

    cout << s2 < < endl//输出HaXXX Potter

十、删除子串

erase 成员函数可以删除 string 对象中的子串,返回值为对象自身的引用。例如:

    string s1("Real Steel");

    s1.erase(1, 3);  //删除子串(1, 3),此后s1 = "R Steel"

    s1.erase(5);  //删除下标及其后面的所有字符,此后s1 = "R Ste"

十一、插入字符串

insert 成员函数可以在 string 对象中插入另一个字符串,返回值为对象自身的引用。例如:

    string s1("Limitless"), s2("00");

    s1.insert(2, "123");  //在下标2 处插入字符串"123"s1 = "Li123mitless"

    s1.insert(3, s2);  //在下标2 处插入s2 , s1 = "Li10023mitless"

    s1.insert(3, 5, 'X');  //在下标3 处插入5 'X's1 = "Li1XXXXX0023mitless"

 

发布了76 篇原创文章 · 获赞 63 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/bjtuwayne/article/details/87109613