C++标准模板库(STL)(1) 之 string类 (自学笔记)

目录

前言

一、string类 头文件

二、string和字符数组简单对比

2.1 定义

2.2 赋值

2.3 附加

2.4 长度

三、string类的构造函数

3.1 string(const char *s)

3.2 string(size_type n, char c)   

3.3 string(const string &str)             

3.4 string()

3.5 string(const char *s, size_type n)

3.6 template

      string(Iter begin, Iter end)

3.7 string(const string &str, string size_type pos = 0, size_type n = npos)

3.8 string(string && str) noexcept

3.9 string(initializer_list it)

3.10 一个简单的测试

四、string类输入方式

4.1 对于C-风格字符串有三种方式

4.2 对于string对象,有两种方式

4.3 cin.getline和getline的区别

五、string类运算符

六、string类关系运算符

七、重载的find()方法及其簇(查找子串)

八、string库实际上基于一个模板类

好文章参考


前言

由于工作需要,要补一下C++的知识,主要是string类、vector模板类和map模板类,以前在学校里学C++只学了类、对象、继承、多态等一些面向对象的基本思想,并没有接触到标准模板库(STL)的内容。本篇文章记录下自己对STL中,string类的学习笔记。以后应该还会继续学习vector(矢量)模板类、map模板类。

初学的同学我们可以交流、补充我的不足,大佬光临还希望能提出建议。无论如何,您的建言我都将感激不尽~。

本文参考书籍:《C++ Primer Plus》。

一、string类 头文件

#include <string>

注意,<string>头文件不同于<string.h>!前者提供了string类,后者提供了C-风格的字符串操作函数。

<string>头文件提供了大量的方法,其中包括了若干构造函数,字符串赋值、合并、比较、查找、字串、重载运算符等。

 

二、string和字符数组简单对比

string声明的是简单变量;字符数组声明的是数组。

string类能让程序自动处理string大小;字符数组定长。

2.1 定义

字符数组:char a[20];  或  char a[20] ="abc cba";  或  char a[] = "abc cba"; 

string类  :string a;      或  string a = "abc cba";

2.2 赋值

字符数组:char b[10];    strcpy(b, a); //数组b必须大于等于数组a的长度。

string类  :string b;        b = a; //没有限制,string类可自动调节string长度

 

使用getline输入时:

字符数组:char a[20];       cin.getline(a,20);    cout << strlen(a); //需要指定最大长度,避免超越数组边界

string类  :string a;           getline(cin, a);        cout << strlen(a);

2.3 附加

字符数组:char c[20] = "#: ";      strcat(c, a); //数组c的长度定义时,必须大于strlen(a)+strlen(c)

string类  :string c = "#: ";          c += a; //string对象c的长度定义时,没有限制

2.4 长度

字符数组:int len1 = strlen(c);

string类  :int len2 = c.size();

       //都去掉'\0'后的长度。

 

只定义,不初始化时的长度

字符数组:char a[20];     cout << strlen(a);  //等于27(一种可能),未初始化时的字符数组长度是”未定义“的,没有意义。

string类  :string a;       cout << a.size();   //等于0,定义的,有意义。

 

 

三、string类的构造函数

缩写NBTS(null-terminated string)表示以空字符结束的字符串--这是传统的C-字符串

 

3.1 string(const char *s)

       解释:将string对象初始化,s指向NBTS      

       实例:   string one("Hank!");   

                     cout << one << endl; 

       结果:Hank

      

3.2 string(size_type n, char c)   

       解释:创建一个包含n个元素的string对象,其中每个元素都被初始化为字符c。

       实例:   string two(4, '$');         

                     cout << two << endl;

       结果:$$$$

      

3.3 string(const string &str)             

       解释:将一个string对象,初始化为string对象str(复制构造函数)

       实例:   string three(one);        

                     cout << three << endl;

       结果:Hank    (复制了one)

      

3.4 string()

       解释:创建一个默认的string对象,长度为0.

       实例:   string four;

                     cout << four << endl;

       结果:(空)

      

3.5 string(const char *s, size_type n)

       解释:将string对象初始化为s指向的NBTS的前n个字符,即使超过了NBTS结尾。

       实例:   char alls[] = "Leiney is my gril-friend!";

                     string five(alls, 6);

                     cout << five << endl;

       结果:Leiney

 

3.6 template<class Iter>

      string(Iter begin, Iter end)

       解释:将string对象初始化为区间[begin, end)内的字符,其中begin和end用于指定位置。Iter看作指针,比如(char *)。所以需要传入指针或地址。注意:第一个字符位置为0。

       实例:   char alls[] = "Leiney is my gril-friend!";

                     string six(alls+0, alls+3);           //方法1,指针方式调用(char *)。范围:[9,11)-->9,10

                     string six_2(&alls[0], &alls[3]);      //方法2,地址方式调用。范围:[9,11)-->9,10

                     cout << six << six_2 << endl;

       结果:LeiLei

      

3.7 string(const string &str, string size_type pos = 0, size_type n = npos)

       解释:将一个string对象初始化为对象str中,从pos位开始到结尾的字符,或从pos位开始之后的n个字符。注意:第一个字符位置为0。

       实例:   char alls[] = "Leiney is my gril-friend!";

                     string seven(alls, 0, 6);

                     cout << seven << endl;

       结果:Leiney

 

3.8 string(string && str) noexcept

       解释:c++11新增,将一个string对象初始化为string对象str,并可能修改str。这是移动构造函数:新建的string为str的副本,与复制构造不同的是,它不保证将str视为const。

       实例:

                     string test(const string & x)

                     {

                            return x;

                     }

                     main()

                     {

                            char alls[] = "Leiney is my gril-friend!"

                            ...

                            string eithg(test(alls));

                            cout << eight << endl;

                            ...

                     }

       结果:Leiney is my gril-friend!

      

3.9 string(initializer_list<char> it)

       解释:C++11新增,将一个string对象初始化为初始化列表il中的字符。(一般来说,用处不大)

       实例:   string nine = {'H', 'a', 'n', 'k'};

                     cout << nine;

       结果:Hank

 

3.10 一个简单的测试

/*************************************************************************
	> File Name: string_1.cpp
	> Author: hank
	> Mail: 34392195@qq.com 
	> Created Time: 2020年07月27日 星期一 19时18分27秒
 ************************************************************************/
#include<iostream>
#include<string>
using namespace std;


string test(const string& x)
{
	return x;
}

int main()
{
	char alls[] = "Leiney is my gril-friend!";

	cout << endl << "***1 string(const char *s)"<< "***" << endl;
	string one("Hank!");
	cout << one << endl;
	//Hank!

	cout << endl << "***2 string(size_type n, char c)" << "***" << endl;
	string two(4,'$');
	cout << two << endl;
	//$$$$

	cout << endl << "***3 string(const string &str)" << "***" << endl;
	string three(one);
	cout << three << endl;
	//Hank!


	cout << endl << "***4 string()" << "***" << endl;
	string four();
	cout << four << endl;
	//
	

	cout << endl << "***5 string(const char *s, size_type n)" << "***" << endl;
	string five(alls, 6);
	cout << five << endl;
	//Leiney


	cout << endl << "***6 template<class Iter> string(Iter begin, Iter end)" << "***" << endl;
	string six(alls + 0, alls + 3);
	string six_2(&alls[0], &alls[3]);
	cout << six << six_2 << endl;
	//LeiLei


	cout << endl << "***7 string(const string &str, string size_type pos = 0, size_type n = npos)" << "***" << endl;
	string seven(alls, 0, 6); 
	cout << seven << endl;
	//Leiney
	
	cout << endl << "***8 string(string && str) noexcept" << "***" << endl;
	string eight(test(alls));
	cout << eight << endl;
	//Leiney is my gril-friend!
	
	cout << endl << "***9 string(initializer_list<char> it)" << "***" << endl;
	string nine = {'H','a','n','k'};
	cout << nine << endl;
	//Hank
	
}

【新手提示】

g++ string_1.cpp -std=c++11  //编译时不要忘了参数

当然,为了方便,可以使用alias 取别名的方式,重新指定g++的编译方式

alias g++ ‘g++ -std=c++11’

以后,直接g++ string_1.cpp就可以了。

 

四、string类输入方式

4.1 对于C-风格字符串有三种方式

char info[100];

(1)cin >> info;                   //输入一个词,从第一个非空白符(如空格/换行符/制表符)到最后一个非空白符。

(2)cin.getline(info, 100);       //输入一行

(3)cin.get(info, 100);             //输入一行

对于cin.getline:读取所有字符,遇到'\n'时止,'\n'从输入缓冲区中删除掉,不影响下一个读操作。

对于cin.get:读取所有字符,遇到'\n'时止,'\n'留在输入缓冲区中。'\n'将影响下一个读操作。

另外,cin.getline可指定输入边界,如指定‘:’代替\n成为输入边界:cin.getline(info, 100, ':');

      

4.2 对于string对象,有两种方式

string stuff;

(1)cin >> stuff;                    //输入一个词,从第一个非空白符(如空格/换行符/制表符)到最后一个非空白符。

(2)geline(cin, stuff);              //输入一行

同样的,getline可指定输入边界,如指定‘:’代替\n成为输入边界:getline(cin, ':');

      

4.3 cin.getline和getline的区别

用于C-风格字符串的cin.geline,不能自动调整字符串的大小。

用于string对象的getline可以自动调整字符串的大小,使其刚好存储一个字符串。

char f1[10];

string f2;

cin.getline(f1, 10);        //可能超出10的限制,造成问题

getline(cin, f2);   //自动调整字符串长度

 

五、string类运算符

       string s1, s2;

       string s2;

       s1 = "hello,";        // ”=“  赋值

       s2 = "Leiney!";

      

       s1 += s2;

       s2 += "I am Hank."      // ”+=“ 追加

                           

       s3 = s1 + s2          // ”+“  拼接

      

       s3 = s1 + "Long time no see!" + " " + s2 + "\n";

 

 

六、string类关系运算符

字符串比较:从前向后,对比每一个字符,按照ASCII值小的,字符串小。

string类对6种关系运算符都进行了重载:!= < <= == >= >

除了6中关系运算符,在关系运算中,常用的还有两个对象:s.empty()、s.size()

s.empty()判断string是否空,空返回true,否则返回false。

s.size()和length()用于获取string的字符个数。length()来自较早版本的string类;size()为STL提供兼容性而添加。

简例:

int main()
{
    string str1;
    getline(cin, str1);        //input relationship

    if(s.size() < 7)           //字节数
    {
        if(s.empty())          //判空
        {
            cout << "string empty" <<endl;
        }
        else if(s == "love")   //关系符
        {    
            cout << "they are fall in love" << endl;
        }
        else
        {
            cout << "relation is not clear" << endl;
        }
    }
    else
    {
        cout << "string input too long" << endl;
    }
    return 0;
}

      

七、重载的find()方法及其簇(查找子串)

string::npos是字符串可存储的最大字符数,通常是无符号int和无符号long的最大取值

方法原型:

(1)size_type find(const string &str, 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_tpye pos = 0, size_type n)

(4)size_type find(const ch, size_type pos = 0)const

对于(1):从字符串pos位置开始,查找子串str。成功则返回首次出现时首字符索引,失败返回string::npos。

对于(2):同(1)

对于(3):从字符串pos位置开始,查找子串s前n个字符组成的字符串。成功则返回首次出现时首字符索引,失败返回string::npos。

对于(4):从字符串pos位置开始,查找字符s。成功则返回首次出现时字符的索引,失败返回string::npos。

      

find相关的其它方法,它们的重载特征都和find相同:

rfind():查找子字符串或字符最后一次出现的位置。

find_first_of():在字符串中,查找字符串参数中任何一个字符,首次出现的位置。

find_last_of():在字符串中,查找字符串参数中任何一个字符,末次出现的位置。

find_first_not_of():在字符串中,查找不是字符串参数中任何一个字符,首次出现的位置。

find_last_not_of():在字符串中,查找不是字符串参数中任何一个字符,末次出现的位置。

 

八、string库实际上基于一个模板类

template<class charT, class traits = char _traits<charT>,

class Allocator = allocator<charT>>

basic_string{...};

 

模板basic_string有4个具体化,每个具体化都有一个typedef名称:

typedef basic_string<char> string;

typedef basic_string<wchar_t> wstring;

typedef basic_string<char16_t> u16string;

typedef basic_string<char32_t> u32string;

 

Allocator是一个管理内存分配的类,他们使用new和delete,申请和注销的过程是自动的。所以数据在堆区。

 

好文章参考

http://c.biancheng.net/view/400.html

https://blog.csdn.net/weixin_33939380/article/details/94093365 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值