1String的一些说明文档格式.docx
- 文档编号:20462513
- 上传时间:2023-01-23
- 格式:DOCX
- 页数:13
- 大小:67.66KB
1String的一些说明文档格式.docx
《1String的一些说明文档格式.docx》由会员分享,可在线阅读,更多相关《1String的一些说明文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
因为历史原因以及为了与C语言兼容,字符串字面值与标准库string类型不是同一种类型。
这一点很容易引起混乱,编程时一定要注意区分字符串字面值和string数据类型的使用,这很重要。
习题
习题3.2
什么是默认构造函数?
习题3.3
列举出三种初始化String对象的方法。
习题3.4
s和s2的值分别是什么?
strings;
intmain(){
strings2;
}
2String的读写
3.2.2
String的读写
我们已在第1章学习了用iostream标准库来读写内置类型的值,如int,double等。
同样地,也可以用iostream和string标准库,使用标准输入输出操作符来读写string对象:
//Note:
#includeandusingdeclarationsmustbeaddedtocompilethiscode
intmain()
{
//emptystring
cin>
>
s;
//readwhitespace-separatedstringintos
cout<
<
s<
endl;
//writestotheoutput
return0;
}
以上程序首先定义命名为s的字符串,第二行代码:
cin>
从标准输入读取string,并将读入的串存储在s中。
string类型的输入操作符:
读取并忽略开头所有的空白字符(如空格,换行符,制表符)。
读取字符直至再次遇到空白字符,读取终止。
因此,如果输入到程序的是“
HelloWorld!
”(注意到开头和结尾的空格),则屏幕上将输出“Hello”,而不含任何空格。
输入和输出操作的行为与内置类型操作符基本类似。
尤其是,这些操作符返回左操作数作为运算结果。
因此,我们可以把多个读操作或多个写操作放在一起:
strings1,s2;
s1>
s2;
//readfirstinputintos1,secondintos2
cout<
s1<
s2<
//writebothstrings
如果给定和上一个程序同样的输入,则输出的结果将是:
HelloWorld!
对于上例,编译时必须加上#include来标示iostream和string标准库,以及给出用到的所有标准库中的名字(如string,cin,cout,endl)的using声明。
从本例开始的程序均假设程序中所有必须的#include和using声明已给出。
1.读入未知数目的string对象
和内置类型的输入操作符一样,string的输入操作符也会返回所读的数据流。
因此,可以把输入操作作为判断条件,这与我们在1.4.4节读取整型数据的程序做法是一样的。
下面的程序将从标准输入读取一组string对象,然后在标准输出上逐行输出:
stringword;
//readuntilend-of-file,writingeachwordtoanewline
while(cin>
word)
word<
上例中,用输入操作符来读取string对象。
该操作符返回所读的istream对象,并在读取结束后,作为while的判断条件。
如果输入流是有效的,即还没到达文件尾且没遇到无效输入,则执行while循环体,并将读取到的字符串输出到标准输出。
如果到达了文件尾,则跳出while循环。
2.用getline读取整行文本
另外还有一个有用的stringIO操作:
getline。
这个函数接受两个参数:
一个输入流对象和一个string对象。
getline函数从输入流的下一行读取,并保存读取的内容到string中,但不包括换行符。
和输入操作符不一样的是,getline并不忽略行开头的换行符。
只要getline遇到换行符,即便它是输入的第一个字符,getline也将停止读入并返回。
如果第一个字符就是换行符,则string参数将被置为空string。
getline函数将istream参数作为返回值,和输入操作符一样也把它用作判断条件。
例如,重写前面那段程序,把每行输出一个单词改为每次输出一行文本:
stringline;
//readlineattimeuntilend-of-file
while(getline(cin,line))
line<
由于line不含换行符,若要逐行输出需要自行添加。
照常,我们用endl来输出一个换行符并刷新输出缓冲区。
注意由于getline函数返回时丢弃换行符,换行符将不会存储在string对象中。
习题3.5
编写程序实现从标准输入每次读入一行文本。
然后改写程序,每次读入一个单词。
习题3.6
解释string类型的输入操作符和getline函数分别如何处理空白字符。
3string对象的操作
3.2.3
string对象的操作
表3-2列出了常用的string操作。
表3-2
string操作
1.string的size和empty操作
string对象的长度指的是string对象中字符的个数,可以通过size操作获取:
stringst("
Theexpenseofspirit\n"
"
Thesizeof"
<
st<
is"
st.size()
characters,includingthenewline"
编译并运行这个程序,得到的结果为:
ThesizeofTheexpenseofspirit
is22characters,includingthenewline
了解string对象是否为空是有用的。
一种方法是将size与0进行比较:
if(st.size()==0)
//ok:
empty
本例中,程序员并不需要知道string对象中有多少个字符,只想知道size是否为0。
用string的成员函数empty()可以更直接地回答这个问题:
if(st.empty())
empty()成员函数将返回bool值(2.1节),如果string对象为空则返回true,否则返回false。
2.string:
size_type类型
从逻辑上来讲,size()成员函数似乎应该返回整型数值,或如2.2节“建议”中所述的无符号整数。
但事实上,size操作返回的是string:
size_type类型的值。
我们需要对这种类型做一些解释。
string类类型和许多其他库类型都定义了一些伙伴类型(companiontypes)。
这些伙伴类型使得库类型的使用是机器无关的(machine-independent)。
size_type就是这些伙伴类型中的一种。
它定义为与unsigned型(unsignedint或unsignedlong)具有相同的含义,而且可以保证足够大可存储任意string对象的长度。
为了使用由string类型定义的size_type类型,程序员必须加上作用域操作符来说明所使用的size_type类型是由string类定义的。
任何存储string的size操作结果的变量必须为string:
size_type类型。
特别重要的是,不要把size的返回值赋给一个int变量。
虽然我们不知道string:
size_type的确切类型,但可以知道它是unsigned型(2.1.1节)。
对于任意一种给定的数据类型,它的unsigned型所能表示的最大正数值比对应的signed要大一倍。
这个事实表明size_type存储的string长度是int所能存储的两倍。
使用int变量的另一个问题是,有些机器上int变量的表示范围太小,甚至无法存储实际并不长的string对象。
如在有16位int型的机器上,int类型变量最大只能表示32767个字符的string对象。
而能容纳一个文件内容的string对象轻易就会超过这个数字。
因此,为了避免溢出,保存一个string对象size的最安全的方法就是使用标准库类型string:
size_type。
3.string关系操作符
string类定义了几种关系操作符用来比较两个string值的大小。
这些操作符实际上是比较每个string对象的字符。
string对象比较运算是区分大小写的,即同一个字符的大小写形式被认为是两个不同的字符。
在多数计算机上,大写的字母位于小写字母之前:
任何一个大写字母都小于任意的小写字母。
==操作符比较两个string对象,如果它们相等,则返回true。
两个string对象相等是指它们的长度相同,且含有相同的字符。
标准库还定义了!
=操作符来测试两个string对象是否不等。
关系操作符<
<
=,>
>
=分别用于测试一个string对象是否小于、小于或等于、大于、大于或等于另一个string对象:
stringbig="
big"
small="
small"
;
strings1=big;
//s1isacopyofbig
if(big==small)
//false
//...
if(big<
=s1)
//true,they'
reequal,sobigislessthanorequaltos1
关系操作符比较两个string对象时采用了和(大小敏感的)字典排序相同的策略:
如果两个string对象长度不同,且短的string对象与长的string对象的前面部分相匹配,则短的string对象小于长的string对象。
如果两个string对象的字符不同,则比较第一个不匹配的字符。
举例来说,给定string对象:
stringsubstr
="
Hello"
stringphrase
HelloWorld"
stringslang
Hiya"
则substr小于phrase,而slang则大于substr或phrase。
4.string对象的赋值
总体上说,标准库类型尽量设计得和基本数据类型一样方便易用。
因此,大多数库类型支持赋值操作。
对string对象来说,可以把一个string对象赋值给另一个string对象:
//st1isanemptystring,st2isacopyoftheliteral
stringst1,st2="
Theexpenseofspirit"
st1=st2;
//replacest1byacopyofst2
赋值操作后,st1就包含了st2串所有字符的一个副本。
大多数string库类型的赋值等操作的实现都会遇到一些效率上的问题,但值得注意的是,从概念上讲,赋值操作确实需要的工作。
它必须先把st1占用的相关内存释放掉,然后再分配给st1足够存放st2副本的内存空间,最后把st2中的所有字符复制到新分配的内存空间。
5.两个string对象相加
string对象的加法被定义为连接(concatenation)。
也就是说,两个(或多个)string对象可以通过使用加操作符+或者复合赋值操作符+=(1.4.1节)连接起来。
给定两个string对象:
strings1("
hello,"
strings2("
world\n"
下面把两个string对象连接起来产生第三个string对象:
strings3=s1+s2;
//s3ishello,world\n
如果要把s2直接追加到s1的末尾,可以使用+=操作符:
s1+=s2;
//equivalenttos1=s1+s2
6.和字符串字面值的连接
上面的字符串对象s1和s2直接包含了标点符号。
也可以通过将string对象和字符串字面值混合连接得到同样的结果:
hello"
world"
strings3=s1+"
"
+s2+"
\n"
当进行string对象和字符串字面值混合连接操作时,+操作符的左右操作数必须至少有一个是string类型的:
strings1="
//nopunctuation
strings2="
addingastringandaliteral
strings4="
+"
//error:
nostringoperand
strings5=s1+"
each+hasstringoperand
strings6="
+s2;
can'
taddstringliterals
S3和s4的初始化只用了一个单独的操作。
在这些例子中,很容易判断s3的初始化是合法的:
把一个string对象和一个字符串字面值连接起来。
而s4的初始化试图将两个字符串字面值相加,因此是非法的。
s5的初始化方法显得有点不可思议,但这种用法和标准输入输出的串联效果是一样的(1.2节)。
本例中,string标准库定义加操作返回一个string对象。
这样,在对s5进行初始化时,子表达式s1+"
将返回一个新string对象,后者再和字面值“world\n”连接。
整个初始化过程可以改写为:
stringtmp=s1+“,”;
+hasastringoperand
s5=tmp+“world”;
而s6的初始化是非法的。
依次来看每个子表达式,则第一个子表达式试图把两个字符串字面值连接起来。
这是不允许的,因此这个语句是错误的。
7.从string对象获取字符
string类型通过下标操作符([])来访问string对象中的单个字符。
下标操作符需要取一个size_type类型的值,来标明要访问字符的位置。
这个下标中的值通常被称为“下标”或“索引(index)”。
string对象的下标从0开始。
如果s是一个string对象且s不空,则s[0]就是字符串的第一个字符,s[1]就表示第二个字符(如果有的话),而s[s.size()-1]则表示s的最后一个字符。
引用下标超出下标作用范围就会引起溢出错误。
可用下标操作符分别取出string对象的每个字符,分行输出:
stringstr("
somestring"
for(string:
size_typeix=0;
ix!
=str.size();
++ix)
str[ix]<
每次通过循环,就从str对象中读取下一个字符,输出该字符并换行。
8.下标操作可用作左值
前面说过,变量是左值(2.3.1节),且赋值操作的左操作数必须是左值。
和变量一样,string对象的下标操作返回值也是左值。
因此,下标操作可以放于赋值操作符的左边或右边。
通过下面循环把str对象的每一个字符置为’*’:
str[ix]='
*'
9.计算下标值
任何可产生整型数值的表达式都可用作下标操作符的索引。
例如,假设someval和someotherval是两个整型对象,可以这样写:
str[someotherval*someval]=someval;
虽然任何整型数值都可作为索引,但索引的实际数据类型却是unsigned类型string:
前面讲过,要用string:
size_type类型的变量接受size函数的返回值。
在定义用作索引的变量时,出于同样的道理,string对象的索引变量最好也用string:
size_type类型。
在使用下标索引string对象时,必须保证索引值“在上下界范围内”。
“在上下界范围内”就是指索引值是一个赋值为size_type类型的值,其取值范围在0到string对象长度减1之间。
使用string:
size_type类型或其他unsigned类型作为索引,就可以保证索引值不小于0。
只要索引值是unsigned类型,就只需要检测它是否小于string对象的长度。
标准库不要求检查索引值,所用索引的下标越界是没有定义的,这样往往会导致严重的运行时错误。
3.2.4
string对象中字符的处理
我们经常要对string对象中的单个字符进行处理,例如,通常需要知道某个特殊字符是否为空白字符、字母或数字。
表3-3列出了各种字符操作函数,适用于string对象的字符(或其他任何char值)。
这些函数都在cctype头文件中定义。
表3-3
cctype定义的函数
表3-3中的大部分函数是测试一个给定的字符是否符合条件,并返回一个int值作为真值。
如果测试失败,则该函数返回0,否则返回一个(无意义的)非0值,表示被测字符符合条件。
表中的这些函数,可输出的字符是指那些可以显式表示的字符。
空白字符则是空格、制表符、垂直制表符、回车符、换行符和进纸符中的任意一种;
标点符号则是除了数字、字母或(可输出的)空白字符(如空格)以外的其他字符。
这里给出一个例子,运用这些函数输出一给定string对象中标点符号的个数:
strings("
HelloWorld!
!
"
string:
size_typepunct_cnt=0;
//countnumberofpunctuationcharactersins
size_typeindex=0;
index!
=s.size();
++index)
if(ispunct(s[index]))
++punct_cnt;
punct_cnt
punctuationcharactersin"
这个程序的输出结果是:
3punctuationcharactersinHelloWorld!
和返回真值的函数不同的是,tolower和toupper函数返回的是字符,返回实参字符本身或返回该字符相应的大小写字符。
我们可以用tolower函数把string对象s中的字母改为小写字母,程序如下:
//convertstolowercase
s[index]=tolower(s[index]);
得到的结果为:
helloworld!
建议:
采用C标准库头文件的C++版本
C++标准库除了定义了一些特定于C++的设施外,还包括C标准库。
C++中的头文件cctype其实就是利用了C标准库函数,这些库函数就定义在C标准库的ctype.h头文件中。
C标准库头文件命名形式为name.h,而C++版本则命名为cname,少了后缀.h而在头文件名前加了c。
c表示这个头文件源自C标准库。
因此,cctype与ctype.h文件的内容是一样的,只是采用了更适合C++程序的形式。
特别地,cname头文件中定义的名字都定义在命名空间std内,而.h版本中的名字却不是这样。
通常,C++程序中应采用cname这种头文件的版本,而不采用name.h版本,这样,标准库中的名字在命名空间std中保持一致。
使用.h版本会给程序员带来负担,因为他们必须记得哪些标准库名字是从C继承来的,而哪些是C++所特有的。
习题3.7
编一程序读入两个string对象,测试它们是否相等。
若不相等,则指出两个中哪个较大。
接着,改写程序测试它们的长度是否相等,若不相等指出哪个较长。
习题3.8
编一程序,从标准输入读取多个string对象,把它们连接起来存放到一个更大的string对
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- String 一些 说明