STL_String类详细解说

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

1STL之String类1前言:string的角色2string使用2.1充分使用string操作符2.2眼花缭乱的stringfind函数2.3stringinsert,replace,erase3string和C风格字符串4string和CharactorTraits5string建议6小结27附录8参考文章前言:string的角色C++语言是个十分优秀的语言,但优秀并不表示完美。还是有许多人不愿意使用C或者C++,为什么?原因众多,其中之一就是C/C++的文本处理功能太麻烦,用起来很不方便。以前没有接触过其他语言时,每当别人这么说,我总是不屑一顾,认为他们根本就没有领会C++的精华,或者不太懂C++,现在我接触perl,php,和Shell脚本以后,开始理解了以前为什么有人说C++文本处理不方便了。举例来说,如果文本格式是:用户名电话号码,文件名name.txtTom23245332Jenny22231231Heny22183942Tom23245332...现在我们需要对用户名排序,且只输出不同的姓名。那么在shell编程中,可以这样用:awk'{print$1}'name.txt|sort|uniq简单吧?3如果使用C/C++就麻烦了,他需要做以下工作:1.先打开文件,检测文件是否打开,如果失败,则退出。2.声明一个足够大得二维字符数组或者一个字符指针数组3.读入一行到字符空间4.然后分析一行的结构,找到空格,存入字符数组中。5.关闭文件6.写一个排序函数,或者使用写一个比较函数,使用qsort排序7.遍历数组,比较是否有相同的,如果有,则要删除,copy...8.输出信息你可以用C++或者C语言去实现这个流程。如果一个人的主要工作就是处理这种类似的文本(例如做apache的日志统计和分析),你说他会喜欢C/C++么?当然,有了STL,这些处理会得到很大的简化。我们可以使用fstream来代替麻烦的fopenfreadfclose,用vector来代替数组。最重要的是用string来代替char*数组,使用sort排序算法来排序,用unique函数来去重。听起来好像很不错。看看下面代码(例程1):#includestring#includeiostream#includealgorithm#includevector#includefstreamusingnamespacestd;intmain(){4ifstreamin(name.txt);stringstrtmp;vectorstringvect;while(getline(in,strtmp,'\n'))vect.push_back(strtmp.substr(0,strtmp.find('')));sort(vect.begin(),vect.end());vectorstring::iteratorit=unique(vect.begin(),vect.end());copy(vect.begin(),it,ostream_iteratorstring(cout,\n));return0;}也还不错吧,至少会比想象得要简单得多!(代码里面没有对错误进行处理,只是为了说明问题,不要效仿).当然,在这个文本格式中,不用vector而使用map会更有扩充性,例如,还可通过人名找电话号码等等,但是使用了map就不那么好用sort了。你可以用map试一试。这里string的作用不只是可以存储字符串,还可以提供字符串的比较,查找等。在sort和unique函数中就默认使用了less和equal_to函数,上面的一段代码,其实使用了string的以下功能:1.存储功能,在getline()函数中2.查找功能,在find()函数中3.子串功能,在substr()函数中4.stringoperator,默认在sort()函数中调用5.stringoperator==,默认在unique()函数中调用总之,有了string后,C++的字符文本处理功能总算得到了一定补充,加上配合STL其他容器使用,其在文本处理上的功能已经与perl,shell,php的距离缩小很多了。因此掌握string会让你的工作事半功倍。5其实,string并不是一个单独的容器,只是basic_string模板类的一个typedef而已,相对应的还有wstring,你在string头文件中你会发现下面的代码:externC++{typedefbasic_stringcharstring;typedefbasic_stringwchar_twstring;}//externC++由于只是解释string的用法,如果没有特殊的说明,本文并不区分string和basic_string的区别。string其实相当于一个保存字符的序列容器,因此除了有字符串的一些常用操作以外,还有包含了所有的序列容器的操作。字符串的常用操作包括:增加、删除、修改、查找比较、链接、输入、输出等。详细函数列表参看附录。不要害怕这么多函数,其实有许多是序列容器带有的,平时不一定用的上。如果你要想了解所有函数的详细用法,你需要查看basic_string,或者下载STL编程手册。这里通过实例介绍一些常用函数。string重载了许多操作符,包括+,+=,,DE=,DE,[],,等,正式这些操作符,对字符串操作非常方便。先看看下面这个例子:tt.cpp(例程2)#includestring#includeiostreamusingnamespacestd;intmain(){stringstrinfo=Pleaseinputyourname:;coutstrinfo;cinstrinfo;if(strinfo==winter)coutyouarewinter!endl;elseif(strinfo!=wende)coutyouarenotwende!endl;elseif(strinfowinter)coutyournameshouldbeaheadofwinterendl;else6coutyournameshouldbeafterofwinterendl;strinfo+=,WelcometoChina!;coutstrinfoendl;coutYournameis:endl;stringstrtmp=Howareyou?+strinfo;for(inti=0;istrtmp.size();i++)coutstrtmp[i];return0;}下面是程序的输出-bash-2.05b$makettc++-O-pipe-march=pentiumprott.cpp-ott-bash-2.05b$./ttPleaseinputyourname:Heroyouarenotwende!Hero,WelcometoChina!Howareyou?Hero,WelcometoChina!有了这些操作符,在STL中仿函数都可以直接使用string作为参数,例如less,great,equal_to等,因此在把string作为参数传递的时候,它的使用和int或者float等已经没有什么区别了。例如,你可以使用:mapstring,intmymap;//以上默认使用了lessstring有了operator+以后,你可以直接连加,例如:stringstrinfo=Winter;stringstrlast=Hello+strinfo+!;//你还可以这样:stringstrtest=Hello+strinfo+Welcome+toChina+!;7看见其中的特点了吗?只要你的等式里面有一个string对象,你就可以一直连续+,但有一点需要保证的是,在开始的两项中,必须有一项是string对象。其原理很简单:1.系统遇到+号,发现有一项是string对象。2.系统把另一项转化为一个临时string对象。3.执行operator+操作,返回新的临时string对象。4.如果又发现+号,继续第一步操作。由于这个等式是由左到右开始检测执行,如果开始两项都是constchar*,程序自己并没有定义两个constchar*的加法,编译的时候肯定就有问题了。有了操作符以后,assign(),append(),compare(),at()等函数,除非有一些特殊的需求时,一般是用不上。当然at()函数还有一个功能,那就是检查下标是否合法,如果是使用:stringstr=winter;//下面一行有可能会引起程序中断错误str[100]='!';//下面会抛出异常:throws:out_of_rangecoutstr.at(100)endl;了解了吗?如果你希望效率高,还是使用[]来访问,如果你希望稳定性好,最好使用at()来访问。由于查找是使用最为频繁的功能之一,string提供了非常丰富的查找函数。其列表如下:函数名描述find查找rfind反向查找find_first_of查找包含子串中的任何字符,返回第一个位置find_first_not_of查找不包含子串中的任何字符,返回第一个位置find_last_of查找包含子串中的任何字符,返回最后一个位置find_last_not_of查找不包含子串中的任何字符,返回最后一个位置8以上函数都是被重载了4次,以下是以find_first_of函数为例说明他们的参数,其他函数和其参数一样,也就是说总共有24个函数:size_typefind_first_of(constbasic_string&s,size_typepos=0)size_typefind_first_of(constcharT*s,size_typepos,size_typen)size_typefind_first_of(constcharT*s,size_typepos=0)size_typefind_first_of(charTc,size_typepos=0)所有的查找函数都返回一个size_type类型,这个返回值一般都是所找到字符串的位置,如果没有找到,则返回string::npos。有一点需要特别注意,所有和string::npos的比较一定要用string::size_type来使用,不要直接使用int或者unsignedint等类型。其实string::npos表示的是-1,看看头文件:templateclass_CharT,class_Traits,class_Allocconstbasic_string_CharT,_Traits,_Alloc::size_typebasic_string_CharT,_Traits,_Alloc::npos=basic_string_CharT,_Traits,_Alloc::size_type)-1;find和rfind都还比较容易理解,一个是正向匹配,一个是逆向匹配,后面的参数pos都是用来指定起始查找位置。对于find_first_of和find_last_of就不是那么好理解。find_first_of是给定一个要查找的字符集,找到这个字符集中任何一个字符所在字符串中第一个位置。或许看一个例子更容易明白。有这样一个需求:过滤一行开头和结尾的所有非英文字符。看看用string如何实现:#includestring#includeiostreamusingnamespacestd;intmain(){stringstrinfo=//*---HelloWord!......------;stringstrset=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz;intfirst=strinfo.find_first_of(strset);if(first==string

1 / 16
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功