《C++程序设计语言》课件第14章_第1页
《C++程序设计语言》课件第14章_第2页
《C++程序设计语言》课件第14章_第3页
《C++程序设计语言》课件第14章_第4页
《C++程序设计语言》课件第14章_第5页
已阅读5页,还剩54页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第14章string类14.1string概述14.2string类的构造函数与析构函数14.3string类重载的操作符14.4string类的成员函数14.5string的基本操作14.6C风格的字符串14.7迭代器14.8字符串流处理小结练习题

本章要点:

string类的构造与析构函数;

string过载的操作符;

string类中的成员函数;

string的基本操作;

string的迭代器;

string的输入/输出流。

14.1string概述

C++本身不支持内置的字符串类型,但它却提供了两种处理字符串的方法:第一,可以利用传统的以Null结束的字符数组(或指针),这种字符串常称为C风格的字符串;第二,一个字符串作为标准库string类的一个实例(对象)进行处理。由于string类不仅使用广泛,而且功能强大且安全可靠(集成了所有对字符串的操作及不会产生越界问题),本章我们将重点讨论string类。实际上,string类是basic_string类的一个子类。basic_string有两个子类:一个是支持其字符为char类型的字符串string类,另一个是支持宽字符w_char字符串的wstring类。因编程中常用char类型的字符串,因此本章我们仅讨论string类。C++标准类库中的string类的定义包含在<string>头文件中。

string类功能非常强大,它有多个过载的构造函数和成员函数。本章我们不可能详尽地介绍其全部内容,仅介绍其最常用的若干功能。一旦读者对string有了一般性的了解,深入探究和掌握string类的其它内容必是水到渠成之事。

14.2string类的构造函数与析构函数

string类提供了一组过载的构造函数,如表14.1所示。下面我们给出利用这些构造函数创建string对象的程序实例。

voidf(char*p,vector<char>&v)

{

strings0;

//创建一个具有空串的string对象s0

strings01=“”;//创建一个具有空串的string对象s01

strings1=‘a’;

//错误!没有从char到string的转换

strings2=7;

//错误!没有从int到string的转换 strings3(7);

//错误!没有取一个整数参数的构造函数

strings4(7,‘a’);

//生成有7个‘a’的string对象,即“aaaaaaa”

strings5=“Frodo”;

//生成一个“Frodo”string对象

strings6=s5;

//生成s5的一个副本

strings7(s5,3,2);

//生成以s5中下标从3开始,字符个数为2的string对象,即“do”

strings8(p+7,3);//生成以p+7开始的3个字符的string对象

strings9(p,7,3); //生成和s8同样的string对象

strings10(v.begin(),v.end()); //生成从v复制所有字符的

string对象

}

14.3string类重载的操作符

string类重载了若干操作符,所重载的操作符如表14.2所示。这些重载的操作符每一种又都具有多种重载形式,具体请参见相关文献和书籍。由于在string类中过载了这些操作符,因此可将这些操作符直接作用于string对象,而不再需要调用诸如strcpy()或strcat()之类的C库函数。又由于string类具有从char*类型到string类型的自动转换功能,因此,运用这些操作符的操作数类型可取string或char*类型。

下面给出一个程序实例,以展示上述过载操作符的基本用法。

//Ashortstringdemonstration

#include<iostream>

#include<string>

usingnamespacestd;

intmain()

{ stringstr1("Alpha");

stringstr2("Beta");

stringstr3("Omega");

stringstr4;

stringstr5(str1);

//outputstringobject

cout<<"Thestringstr5is"<<str5<<endl;

//assignastring

str4=str1;

cout<<"Thestringstr1is"<<str1<<endl;

cout<<"Thestringstr4is"<<str4<<endl;

//concatenatetwostrings

str4=str1+str2;

cout<<"Thestringstr4is"<<str4<<endl;

//concatenateastringwithaC-string

str4=str1+"to"+str3;

cout<<"Thestringstr4is"<<str4<<endl;

//comparestrings

cout<<"str3>str1is"<<str3>str1<<endl;

cout<<"str2==str1is"<<str2==str1<<endl;

cout<<"Thestr3[4]is"<<str1[3]<<endl; //assignC-stringtoastringobject

str1=“Thisisanull_terminatedstring.\n”;

cout<<str1;

//inputstring

cin>>str5;

cout<<“Thestringstr5is”<<str5<<endl;

return0;

}

程序运行输出结果:

Thestringstr5isAlpha

Thestringstr1isAlpha

Thestringstr4isAlpha

Thestringstr4isAlphaBeta

Thestringstr4isAlphatoOmega

str3>str1is1

str2==str1is0

Thestr3[4]ish

Thisisanull_terminatedstring.

STL //键盘输入STL给str5

Thestringstr5isSTL

值得注意的是:string类的对象中没有字符串结束符,另外,string类对象会自动调整其存储尺寸以存放相应长度的字符串。因此,当分配或连接字符串时,目标字符串会根据需求扩展其大小以便适应新的字符串长度,所以string对象不会出现越界问题。string对象的这种动态特性是它们优于以Null结束的C风格字符串的诸多方面之一。

14.4string类的成员函数

虽然利用string过载的操作符可方便地实现对string/char*对象的操作,但更复杂和精细的操作仍需要string的成员函数完成。string类提供了大量的成员函数,以完成string类对象的基本字符串的各种操作,如串接、复制、按下标访问元素、插入、删除等操作。表14.3列出了string类的一些常用成员函数。

14.5string的基本操作

14.5.1元素访问

可以通过string类过载的下标运算符[]和提供的成员函数at()对string对象进行元素访问。两类操作的界面如下:

//不带越界检查的元素访问

conststring&operator[](size_typen)const;

string&operator[](size_typen);

//带有越界检查的元素访问

conststring&at(size_typen)const;

string&at(size_typen);用at()方法访问string对象中的元素时,当发生越界时系统将抛出out_of_range异常。

string缺少front()(取第一个元素)和back()(取最后一个元素)方法。因此,要访问一个string对象s的第一个和最后一个元素,必须采用s[0]和s[s.length()-1]的方式进行。另外需注意的是,&s[0]不等于s。14.5.2赋值

string的赋值操作由过载的赋值运算符“=”和成员函数assign()提供。两类操作的界面如下:

string&operator=(conststring&s);

string&operator=(constchar*s);

string&operator=(constcharc);

string&assign(conststring&s);

string&assign(conststring&s,size_typestart,size_typenum);

string&assign(constchar*p,size_typenum);

string&assign(constchar*p);

string&assign(size_typenum,charc);

template<classT>string&assign(Tfirst,Tlast);

在赋值操作中,C++仍然采用的是值赋值,亦即在将一个串赋值给另一个串时,被赋值的串将被复制,赋值之后存在着两个相互独立的同样的串。例如:

voidg()

{

strings1=“Teacher”;

strings2="Student";

s1=s2;//s1和s2都是“Student”,且相互独立

}

注意上述第三种赋值过载算符形式,它提供了将字符赋给一个string的方法(但不允许用赋值初始化一个新的string对象)。例如:

strings=‘a’; //错误!不允许用char初始化一个string对象

s=‘a’;

//可以用一个char赋给一个string对象14.5.3从string转换到C风格的字符串

可以用一个char*(C风格的字符串)去初始化或赋值给一个string对象。反过来,string类提供了一个从string类到char*的转换,这个功能可用如下成员函数实现:

constchar*c_str()const;

constchar*data()const;

size_typecopy(char*p,size_typenum,size_typestart=0)const;

c_str()函数很像data(),只是它在最后加上了一个串结束符0。换句话说,data()产生的是字符数组,而c_str()产生的是一个C风格的字符串。以上函数主要是允许使用以C风格字符串为参数的函数。下面给出两个程序实例,以展示上述三个成员函数的基本用法。14.5.4字符串的比较

一个string串既可以和同类型的string串进行比较,也可以和char*类型的串进行比较。在string中实现字符串比较可采用过载的关系运算符和compare()成员函数。下面是compare()成员函数接口:

intcompare(conststring&s)const;

intcompare(constchar*p)const;

intcompare(size_typestart,size_typenum,conststring&s)const;

intcompare(size_typestart,size_typenum,conststring&s,size_typestart1,size_type um1)const;

intcompare(size_typestart,size_typenum,constchar*p,size_typenum1=npos)const;

如果compare()函数的参数中提供了比较位置和大小,那么比较中就只用指定的子串进行比较。两个串的比较是按其字符的字典次序进行的,若小于,则返回一个负值,等于返回值0,大于则返回一个正值。下面给出一个程序示例,以展示字符串比较操作。程序运行输出结果:

s1:Testingthecomparisonfunctions.

s2:Hello

s3:stinger

z1:Hello

s1>z1

pare(s2)>0

pare(2,5,s3,0,5)==0

pare(0,s2.size(),s2)==014.5.5附加与插入

一旦建立了一个串,就可以对其进行附加操作,该操作是由string类过载的操作符+、+=以及append()成员函数实现的。

另外,也可以在一个串的某个字符位置前进行插入操作,这是由insert()成员函数实现的。因为insert()操作会带来串中多个字符的移动,所以,该操作的效率低于附加操作的

效率。

在string类中操作符+、+=具有多种过载形式,同样,append()和insert()也有多种过载形式,在此不一一列举,有兴趣的读者请参阅相关文献或书籍。14.5.6查找子串

在string中提供了大量的多种形式的查找子串的成员函数。这些成员函数都是const成员函数,它们找出子串的下标位置而不修改串的值。该功能是由find()、rfind()、find_first_of()、find_last_of()、find_first_not_of()、find_last_not_of()实现的。由于查找子串的成员函数太多,我们在此不一一列举。有兴趣的读者请参阅相关文献或书籍。

利用各种形式的find()查找子串位置时,若没有找到,则函数返回一个npos,它表示一个非法的字符位置,此时系统会抛出out_of_range异常。正常情况下,find()函数应返回一个unsigned类型(size_type)的值。

(find)“subtree”wasfoundat:23

(rfind)“subtree”wasfoundat:102

(find_first_of)characterfrom“qpxz”at:62

(find_last_of)characterfrom“qpxz”at:144

(find_first_not_of)firstcharacternot

containedin“heTvlusinodrpayft”:25

(find_last_not_of)firstcharacternot

containedin"heTvlusinodrpayft":12114.5.7替换

在string中提供了多种过载形式的replace()方法用于实现用一些新的字符去替换一个子串。replace方法的接口如下:在进行了字符串的替换动作后,新串将根据情况做大小尺寸的动态调整。

replace()方法的简单应用见下例:

void()

{

strings=“butIhavehearditwordsevenifyoudon‘tbelieveinit.”;

s.erase(0,4);

//删除s中开始的“but”

s.replace(s.find(“evem”),4,“only”);//用“only”替换“even”

s.replace(s.find(“don’t”),5,“”); //用“”替换“don‘t”

}14.5.8求子串

求string对象的子串的方法是substr()方法。substr的接口如下:

string&substr(size_typestart,size_typenum=npos)const14.5.9string对象的大小和容量

求string对象的大小和容量是通过如下string类成员函数实现的:

size_typesize()const;

size_typemax_size()const;

size_typelength()const;

boolempty()const;

voidresize(size_typenum,charc);

voidresize(size_typenum);

size_typecapacity()const;

voidreserve(res_arg=0);

Allocatorget_allocator()const;//获得内存分配管理器14.5.10输入输出

可利用string类中过载的>>和<<运算符进行string对象的输入输出。利用>>运算符进行字符串的输入时,当遇到whitespace时,输入自动结束。此时可利用string中的getline()方法从输入流中读入一整行字符(以eol结束的字符串)。下面给出一个程序示例,以展示string对象的输入输出方法。程序运行输出结果:

Pleaseenteryourname:Liyanni

Hello,Liyanni!

Pleaseenteryourname:Liyanni

Hello,Li!

从以上示例程序可看出,“>>”运算符只读入串中第一个空白处前的字符串,欲读入整个字符串,需采用getline()方法。

14.6C风格的字符串

所谓C风格的字符串,即带有串结束符Null或0值的串。在C标准例程库中提供了若干对C风格字符串操作的函数,下面我们进行简要介绍。14.6.1C字符串操作函数

在C标准例程库(<string.h>(老版本库)和<cstring>(新标准库))中提供了若干操作C风格字符串的函数,它们是:

char*strcpy(char*p,constchar*q);

//复制q到p,包括串结束符

char*strcat(char*p,constchar*q);

//将q附加到p后,包括串结束符

char*strncpy(char*p,constchar*q,intn);

//从q复制n个字符到p中,

包括串结束符

char*strncat(char*p,constchar*q,intn);

//将q的n个字符附加到p

后,包括串结束符

size_tstrlen(constchar*p);

//求串的长度,不计串结束符14.6.2将数值字符串转换到数值的函数

在<stdlib.h>(老版本库)和<cstdlib>(新标准库)中提供了几个很有用的将表示数值的字符串转换到数值的函数,它们是:

//将p[]转换到double(字母到double数值)

doubleatof(constchar*p);

//将p[]转换到double(字符串到double数值)

doublestrtod(constchar*p,char**end);

//将p[]转换到int,假定基数为10

intatoi(constchar*p);

//将p[]的字符转换到long,假定基数为10

longatol(constchar*p);

//将p[]的字符串转换到long,假定基数为b

longstrtol(constchar*p,char**end,intb)14.6.3字符分类

在<ctype.h>和<cctype>中,标准库提供了一组很有用的函数,用于处理ASCII或者其它类似的字符集:

intisalpha(intc);//判断c是否为字母字符

intisupper(intc);//判断c是否为大写字母字符

intislower(intc);//判断c是否为小写字母字符

intisdigit(intc);//判断c是否为十进制数字字母字符

intisxdigit(intc);//判断c是否为十六进制数字字母字符

intisspace(intc); //判断c是否为空格或换行等字符

itniscntrl(intc); //判断c是否为控制字符

intispunct(intc); //判断c是否为标点符号字符

intisalnum(intc); //判断c是否为字母/数字字符

intisprint(intc); //判断c是否为可打印字符

intisgraph(intc); //判断c是否为字母/数字/标点符

号字符

inttoupper(intc); //将c转换成大写

inttolower(intc); //将c转换成小写

14.7迭代器

string类提供了向前(逆序)和向后(顺序)遍历string中字符的迭代器(Iterator)。迭代器类似于指针,但其忽略所指对象的类别。通过迭代器可访问string对象中的字符。注意:利用迭代器访问串中的字符时,它不检查string对象串的范围。string类提供向后遍历的常量迭代器string::const_iterator和非常量迭代器string::iterator,它同时还提供向前遍历的常量迭代器const_reverse_iterators和非常量迭代器reverse_iterators。其中常量迭代器不能修改所迭代的字符串中的内容,而非常量迭代器可修改所迭代的字符串中的内容。在采用迭代器向后访问串中的内容时,string类提供了成员函数begin(获得串的起始位置)和end(获得串中最后一个字符的下一个字符的位置);向前访问串中的内容时,string类提供了成员函数rbegin(获得串的起始位置)和rend(获得串中最后一个字符的下一个字符的位置)。类string迭代器及相应的成员函数请参见表14.3。下面给出string迭代器的一个简单应用示例。程序运行输出结果:

s=Testingiterators

(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论