<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://www.jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://www.jackxiang.com/post//</link>
<title><![CDATA[C++ string 详解]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Fri, 07 Mar 2008 05:20:25 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	#include &quot;iostream&quot;<br/>#include &quot;../../lib/sinalib/StrLib/str.h&quot;<br/>#include &quot;StrLib.h&quot;<br/>using namespace std;<br/><br/>int main()<br/>{<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string&nbsp;&nbsp;strinfo=&quot;Please input your name:&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout &lt;&lt; strinfo ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cin &gt;&gt; strinfo;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( strinfo == &quot;winter&quot; )<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout &lt;&lt; &quot;you are winter!&quot;&lt;&lt;endl;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strinfo += &quot; , Welcome to China!&quot;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout &lt;&lt; strinfo ;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string strtmp = &quot;How are you? &quot; + strinfo;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int i = 0 ; i &lt; strtmp.size(); i ++) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cout&lt;&lt;strtmp&lt;&lt;strtmp.size();&nbsp;&nbsp;&nbsp;&nbsp;<br/><br/>}<br/><br/><br/>前言: string 的角色 <br/>1 string 使用 <br/>1.1 充分使用string 操作符 <br/>1.2 眼花缭乱的string find 函数 <br/>1.3 string insert, replace, erase 2 string 和 C风格字符串 <br/>3 string 和 Charactor Traits <br/>4 string 建议 <br/>5 小结 <br/>6 附录前言: string 的角色 <br/><br/>C++ 语言是个十分优秀的语言，但优秀并不表示完美。还是有许多人不愿意使用C或者C++，为什么？原因众多，其中之一就是C/C++的文本处理功能太麻烦，用起来很不方便。以前没有接触过其他语言时，每当别人这么说，我总是不屑一顾，认为他们根本就没有领会C++的精华，或者不太懂C++，现在我接触perl, php, 和Shell脚本以后，开始理解了以前为什么有人说C++文本处理不方便了。 <br/><br/>举例来说，如果文本格式是：用户名 电话号码，文件名name.txt <br/>Tom 23245332<br/>Jenny 22231231<br/>Heny 22183942<br/>Tom 23245332<br/>... <br/><br/>现在我们需要对用户名排序，且只输出不同的姓名。 <br/><br/>那么在shell 编程中，可以这样用： <br/>awk &#039;{print $1}&#039; name.txt &#124; sort &#124; uniq <br/><br/>简单吧？ <br/><br/>如果使用C/C++ 就麻烦了，他需要做以下工作： <br/>先打开文件，检测文件是否打开，如果失败，则退出。 <br/>声明一个足够大得二维字符数组或者一个字符指针数组 <br/>读入一行到字符空间 <br/>然后分析一行的结构，找到空格，存入字符数组中。 <br/>关闭文件 <br/>写一个排序函数，或者使用写一个比较函数，使用qsort排序 <br/>遍历数组，比较是否有相同的，如果有，则要删除，copy... <br/>输出信息 <br/><br/>你可以用C++或者C语言去实现这个流程。如果一个人的主要工作就是处理这种类似的文本(例如做apache的日志统计和分析),你说他会喜欢C/C++么？ <br/><br/>当然，有了STL，这些处理会得到很大的简化。我们可以使用 fstream来代替麻烦的fopen fread fclose, 用vector 来代替数组。最重要的是用 string来代替char * 数组，使用sort排序算法来排序，用unique 函数来去重。听起来好像很不错 。看看下面代码(例程1）： <br/>＃i nclude &lt;string&gt;<br/>＃i nclude &lt;iostream&gt;<br/>＃i nclude &lt;algorithm&gt;<br/>＃i nclude &lt;vector&gt;<br/>＃i nclude &lt;fstream&gt;<br/>using namespace std;<br/>int main(){<br/>ifstream in(&quot;name.txt&quot;);<br/>string strtmp;<br/>vector&lt;string&gt; vect;<br/>while(getline(in, strtmp, &#039;&#92;n&#039;))<br/>vect.push_back(strtmp.substr(0, strtmp.find(&#039; &#039;)));<br/>sort(vect.begin(), vect.end());<br/>vector&lt;string&gt;::iterator it=unique(vect.begin(), vect.end());<br/>copy(vect.begin(), it, ostream_iterator&lt;string&gt;(cout, &quot;&#92;n&quot;));<br/>return 0;<br/>} <br/><br/>也还不错吧，至少会比想象得要简单得多！（代码里面没有对错误进行处理，只是为了说明问题，不要效仿). <br/><br/>当然，在这个文本格式中，不用vector而使用map会更有扩充性，例如，还可通过人名找电话号码等等，但是使用了map就不那么好用sort了。你可以用map试一试。 <br/><br/>这里string的作用不只是可以存储字符串，还可以提供字符串的比较，查找等。在sort和unique函数中就默认使用了less 和equal_to函数, 上面的一段代码，其实使用了string的以下功能： <br/>存储功能，在getline() 函数中 <br/>查找功能，在find() 函数中 <br/>子串功能，在substr() 函数中 <br/>string operator &lt; , 默认在sort() 函数中调用 <br/>string operator == , 默认在unique() 函数中调用 <br/><br/>总之，有了string 后，C++的字符文本处理功能总算得到了一定补充，加上配合STL其他容器使用，其在文本处理上的功能已经与perl, shell, php的距离缩小很多了。 因此掌握string 会让你的工作事半功倍。 <br/><br/>1 string 使用 <br/><br/>其实，string并不是一个单独的容器，只是basic_string 模板类的一个typedef 而已，相对应的还有wstring, 你在string 头文件中你会发现下面的代码: <br/><br/>extern &quot;C++&quot; {<br/>typedef basic_string &lt;char&gt; string;<br/>typedef basic_string &lt;wchar_t&gt; wstring;<br/>} // extern &quot;C++&quot; <br/><br/>由于只是解释string的用法，如果没有特殊的说明，本文并不区分string 和 basic_string的区别。 <br/><br/>string 其实相当于一个保存字符的序列容器，因此除了有字符串的一些常用操作以外，还有包含了所有的序列容器的操作。字符串的常用操作包括：增加、删除、修改、查找比较、链接、输入、输出等。详细函数列表参看附录。不要害怕这么多函数，其实有许多是序列容器带有的，平时不一定用的上。 <br/><br/>如果你要想了解所有函数的详细用法，你需要查看basic_string，或者下载STL编程手册。这里通过实例介绍一些常用函数。 <br/>1.1 充分使用string 操作符 <br/><br/>string 重载了许多操作符，包括 +, +=, &lt;, =, , [], &lt;&lt;, &gt;&gt;等，正式这些操作符，对字符串操作非常方便。先看看下面这个例子：tt.cpp（例程2） <br/><br/>＃i nclude &lt;string&gt;<br/>＃i nclude &lt;iostream&gt;<br/>using namespace std;<br/>int main(){<br/>string strinfo=&quot;Please input your name:&quot;;<br/>cout &lt;&lt; strinfo ;<br/>cin &gt;&gt; strinfo;<br/>if( strinfo == &quot;winter&quot; )<br/>cout &lt;&lt; &quot;you are winter!&quot;&lt;&lt;endl;<br/>else if( strinfo != &quot;wende&quot; )<br/>cout &lt;&lt; &quot;you are not wende!&quot;&lt;&lt;endl;<br/>else if( strinfo &lt; &quot;winter&quot;)<br/>cout &lt;&lt; &quot;your name should be ahead of winter&quot;&lt;&lt;endl;<br/>else <br/>cout &lt;&lt; &quot;your name should be after of winter&quot;&lt;&lt;endl;<br/>strinfo += &quot; , Welcome to China!&quot;;<br/>cout &lt;&lt; strinfo&lt;&lt;endl;<br/>cout &lt;&lt;&quot;Your name is :&quot;&lt;&lt;endl;<br/>string strtmp = &quot;How are you? &quot; + strinfo;<br/>for(int i = 0 ; i &lt; strtmp.size(); i ++)<br/>cout&lt;&lt;strtmp;<br/>return 0;<br/>} <br/><br/>下面是程序的输出 <br/>-bash-2.05b$ make tt<br/>c++ -O -pipe -march=pentiumpro tt.cpp -o tt<br/>-bash-2.05b$ ./tt<br/>Please input your name:Hero<br/>you are not wende!<br/>Hero , Welcome to China!<br/>How are you? Hero , Welcome to China! <br/><br/>有了这些操作符，在STL中仿函数都可以直接使用string作为参数，例如 less, great, equal_to 等，因此在把string作为参数传递的时候，它的使用和int 或者float等已经没有什么区别了。例如，你可以使用： <br/>map&lt;string, int&gt; mymap;<br/>//以上默认使用了 less&lt;string&gt; <br/><br/>有了 operator + 以后，你可以直接连加，例如： <br/><br/>string strinfo=&quot;Winter&quot;;<br/>string strlast=&quot;Hello &quot; + strinfo + &quot;!&quot;;<br/>//你还可以这样：<br/>string strtest=&quot;Hello &quot; + strinfo + &quot; Welcome&quot; + &quot; to China&quot; + &quot; !&quot;; <br/><br/>看见其中的特点了吗？只要你的等式里面有一个 string 对象，你就可以一直连续&quot;+&quot;，但有一点需要保证的是，在开始的两项中，必须有一项是 string 对象。其原理很简单： <br/><br/>系统遇到&quot;+&quot;号，发现有一项是string 对象。 <br/>系统把另一项转化为一个临时 string 对象。 <br/>执行 operator + 操作，返回新的临时string 对象。 <br/>如果又发现&quot;+&quot;号，继续第一步操作。 <br/><br/>由于这个等式是由左到右开始检测执行，如果开始两项都是const char* ，程序自己并没有定义两个const char* 的加法，编译的时候肯定就有问题了。 <br/><br/>有了操作符以后，assign(), append(), compare(), at()等函数，除非有一些特殊的需求时，一般是用不上。当然at()函数还有一个功能，那就是检查下标是否合法，如果是使用： <br/>string str=&quot;winter&quot;;<br/>//下面一行有可能会引起程序中断错误<br/>str[100]=&#039;!&#039;;<br/>//下面会抛出异常:throws: out_of_range<br/>cout&lt;&lt;str.at(100)&lt;&lt;endl; <br/><br/>了解了吗？如果你希望效率高，还是使用[]来访问，如果你希望稳定性好，最好使用at()来访问。 <br/><br/>1.2 眼花缭乱的string find 函数 <br/><br/>由于查找是使用最为频繁的功能之一，string 提供了非常丰富的查找函数。其列表如下： <br/>函数名 描述 find 查找 rfind 反向查找 find_first_of 查找包含子串中的任何字符，返回第一个位置 find_first_not_of 查找不包含子串中的任何字符，返回第一个位置 find_last_of 查找包含子串中的任何字符，返回最后一个位置 find_last_not_of 查找不包含子串中的任何字符，返回最后一个位置 以上函数都是被重载了4次，以下是以find_first_of 函数为例说明他们的参数，其他函数和其参数一样，也就是说总共有24个函数 ： <br/><br/>size_type find_first_of(const basic_string&amp; s, size_type pos = 0)<br/>size_type find_first_of(const charT* s, size_type pos, size_type n)<br/>size_type find_first_of(const charT* s, size_type pos = 0)<br/>size_type find_first_of(charT c, size_type pos = 0) <br/><br/>所有的查找函数都返回一个size_type类型，这个返回值一般都是所找到字符串的位置，如果没有找到，则返回string::npos。有一点需要特别注意，所有和string::npos的比较一定要用string::size_type来使用，不要直接使用int 或者unsigned int等类型。其实string::npos表示的是-1, 看看头文件： <br/><br/>template &lt;class _CharT, class _Traits, class _Alloc&gt; <br/>const basic_string&lt;_CharT,_Traits,_Alloc&gt;::size_type <br/>basic_string&lt;_CharT,_Traits,_Alloc&gt;::npos <br/>= basic_string&lt;_CharT,_Traits,_Alloc&gt;::size_type) -1; <br/><br/>find 和 rfind 都还比较容易理解，一个是正向匹配，一个是逆向匹配，后面的参数pos都是用来指定起始查找位置。对于find_first_of 和find_last_of 就不是那么好理解。 <br/><br/>find_first_of 是给定一个要查找的字符集，找到这个字符集中任何一个字符所在字符串中第一个位置。或许看一个例子更容易明白。 <br/><br/>有这样一个需求：过滤一行开头和结尾的所有非英文字符。看看用string 如何实现： <br/>＃i nclude &lt;string&gt;<br/>＃i nclude &lt;iostream&gt;<br/>using namespace std;<br/>int main(){<br/>string strinfo=&quot; //*---Hello Word!......------&quot;;<br/>string strset=&quot;ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz&quot;;<br/>int first = strinfo.find_first_of(strset);<br/>if(first == string::npos) { <br/>cout&lt;&lt;&quot;not find any characters&quot;&lt;&lt;endl;<br/>return -1;<br/>} <br/>int last = strinfo.find_last_of(strset);<br/>if(last == string::npos) { <br/>cout&lt;&lt;&quot;not find any characters&quot;&lt;&lt;endl;<br/>return -1;<br/>} <br/>cout &lt;&lt; strinfo.substr(first, last - first + 1)&lt;&lt;endl;<br/>return 0;<br/>} <br/><br/>这里把所有的英文字母大小写作为了需要查找的字符集，先查找第一个英文字母的位置，然后查找最后一个英文字母的位置，然后用substr 来的到中间的一部分，用于输出结果。下面就是其结果： <br/><br/>Hello Word <br/><br/>前面的符号和后面的符号都没有了。像这种用法可以用来查找分隔符，从而把一个连续的字符串分割成为几部分，达到 shell 命令中的 awk 的用法。特别是当分隔符有多个的时候，可以一次指定。例如有这样的需求： <br/><br/>张三&#124;3456123, 湖南<br/>李四,4564234&#124; 湖北<br/>王小二, 4433253&#124;北京<br/>... <br/><br/>我们需要以 &quot;&#124;&quot; &quot;,&quot;为分隔符，同时又要过滤空格，把每行分成相应的字段。可以作为你的一个家庭作业来试试，要求代码简洁。 <br/>1.3 string insert, replace, erase <br/>了解了string 的操作符，查找函数和substr，其实就已经了解了string的80%的操作了。insert函数, replace函数和erase函数在使用起来相对简单。下面以一个例子来说明其应用。 <br/>string只是提供了按照位置和区间的replace函数，而不能用一个string字串来替换指定string中的另一个字串。这里写一个函数来实现这个功能： <br/><br/>void string_replace(string &amp; strBig, const string &amp; strsrc, const string &amp;strdst) {<br/>string::size_type pos=0;<br/>string::size_type srclen=strsrc.size();<br/>string::size_type dstlen=strdst.size();<br/>while( (pos=strBig.find(strsrc, pos)) != string::npos){<br/>strBig.replace(pos, srclen, strdst);<br/>pos += dstlen;<br/>}<br/>}看看如何调用： <br/>＃i nclude &lt;string&gt;<br/>＃i nclude &lt;iostream&gt;<br/>using namespace std;<br/>int main() {<br/>string strinfo=&quot;This is Winter, Winter is a programmer. Do you know Winter?&quot;;<br/>cout&lt;&lt;&quot;Orign string is :&#92;n&quot;&lt;&lt;strinfo&lt;&lt;endl;<br/>string_replace(strinfo, &quot;Winter&quot;, &quot;wende&quot;);<br/>cout&lt;&lt;&quot;After replace Winter with wende, the string is :&#92;n&quot;&lt;&lt;strinfo&lt;&lt;endl;<br/>return 0;<br/>}其输出结果： <br/>Orign string is :<br/>This is Winter, Winter is a programmer. Do you know Winter?<br/>After replace Winter with wende, the string is :<br/>This is wende, wende is a programmer. Do you know wende?如果不用replace函数，则可以使用erase和insert来替换，也能实现string_replace函数的功能： <br/>void string_replace(string &amp; strBig, const string &amp; strsrc, const string &amp;strdst) {<br/>string::size_type pos=0;<br/>string::size_type srclen=strsrc.size();<br/>string::size_type dstlen=strdst.size();<br/>while( (pos=strBig.find(strsrc, pos)) != string::npos){<br/>strBig.erase(pos, srclen);<br/>strBig.insert(pos, strdst);<br/>pos += dstlen;<br/>}<br/>}当然，这种方法没有使用replace来得直接。 <br/>2 string 和 C风格字符串 <br/>现在看了这么多例子，发现const char* 可以和string 直接转换，例如我们在上面的例子中，使用 <br/>string_replace(strinfo, &quot;Winter&quot;, &quot;wende&quot;);来代用 <br/>void string_replace(string &amp; strBig, const string &amp; strsrc, const string &amp;strdst) 在C语言中只有char* 和 const char*，为了使用起来方便，string提供了三个函数满足其要求： <br/>const charT* c_str() const <br/>const charT* data() const <br/>size_type copy(charT* buf, size_type n, size_type pos = 0) const 其中： <br/>c_str 直接返回一个以&#92;0结尾的字符串。 <br/>data 直接以数组方式返回string的内容，其大小为size()的返回值，结尾并没有&#92;0字符。 <br/>copy 把string的内容拷贝到buf空间中。 <br/>你或许会问，c_str()的功能包含data()，那还需要data()函数干什么？看看源码： <br/>const charT* c_str () const<br/>{ if (length () == 0) return &quot;&quot;; terminate (); return data (); }原来c_str()的流程是：先调用terminate()，然后在返回data()。因此如果你对效率要求比较高，而且你的处理又不一定需要以&#92;0的方式结束，你最好选择data()。但是对于一般的C函数中，需要以const char*为输入参数，你就要使用c_str()函数。 <br/>对于c_str() data()函数，返回的数组都是由string本身拥有，千万不可修改其内容。其原因是许多string实现的时候采用了引用机制，也就是说，有可能几个string使用同一个字符存储空间。而且你不能使用sizeof(string)来查看其大小。详细的解释和实现查看Effective STL的条款15：小心string实现的多样性。 <br/><br/>另外在你的程序中，只在需要时才使用c_str()或者data()得到字符串，每调用一次，下次再使用就会失效，如： <br/><br/>string strinfo(&quot;this is Winter&quot;);<br/>...<br/>//最好的方式是:<br/>foo(strinfo.c_str());<br/>//也可以这么用:<br/>const char* pstr=strinfo.c_str();<br/>foo(pstr);<br/>//不要再使用了pstr了, 下面的操作已经使pstr无效了。<br/>strinfo += &quot; Hello!&quot;;<br/>foo(pstr);//错误！会遇到什么错误？当你幸运的时候pstr可能只是指向&quot;this is Winter Hello!&quot;的字符串，如果不幸运，就会导致程序出现其他问题，总会有一些不可遇见的错误。总之不会是你预期的那个结果。 <br/><br/>3 string 和 Charactor Traits <br/>了解了string的用法，该详细看看string的真相了。前面提到string 只是basic_string的一个typedef。看看basic_string 的参数： <br/>template &lt;class charT, class traits = char_traits&lt;charT&gt;,<br/>class Allocator = allocator&lt;charT&gt; &gt;<br/>class basic_string<br/>{<br/>//...<br/>}char_traits不仅是在basic_string 中有用，在basic_istream 和 basic_ostream中也需要用到。 <br/>就像Steve Donovan在过度使用C++模板中提到的，这些确实有些过头了，要不是系统自己定义了相关的一些属性，而且用了个typedef，否则还真不知道如何使用。 <br/><br/>但复杂总有复杂道理。有了char_traits，你可以定义自己的字符串类型。当然，有了char_traits &lt; char &gt; 和char_traits &lt; wchar_t &gt; 你的需求使用已经足够了，为了更好的理解string ，咱们来看看char_traits都有哪些要求。 <br/><br/>如果你希望使用你自己定义的字符，你必须定义包含下列成员的结构： 表达式 描述 <br/>char_type 字符类型 <br/>int_type int 类型 <br/>pos_type 位置类型 <br/>off_type 表示位置之间距离的类型 <br/>state_type 表示状态的类型 <br/>assign(c1,c2) 把字符c2赋值给c1 <br/>eq(c1,c2) 判断c1,c2 是否相等 <br/>lt(c1,c2) 判断c1是否小于c2 <br/>length(str) 判断str的长度 <br/>compare(s1,s2,n) 比较s1和s2的前n个字符 <br/>copy(s1,s2, n) 把s2的前n个字符拷贝到s1中 <br/>move(s1,s2, n) 把s2中的前n个字符移动到s1中 <br/>assign(s,n,c) 把s中的前n个字符赋值为c <br/>find(s,n,c) 在s的前n个字符内查找c <br/>eof() 返回end-of-file <br/>to_int_type(c) 将c转换成int_type <br/>to_char_type(i) 将i转换成char_type <br/>not_eof(i) 判断i是否为EOF <br/>eq_int_type(i1,i2) 判断i1和i2是否相等 <br/>想看看实际的例子，你可以看看sgi STL的char_traits结构源码. <br/><br/>现在默认的string版本中，并不支持忽略大小写的比较函数和查找函数，如果你想练练手，你可以试试改写一个char_traits , 然后生成一个case_string类, 也可以在string 上做继承，然后派生一个新的类，例如：ext_string，提供一些常用的功能，例如： <br/><br/>定义分隔符。给定分隔符，把string分为几个字段。 <br/>提供替换功能。例如，用winter, 替换字符串中的wende <br/>大小写处理。例如，忽略大小写比较，转换等 <br/>整形转换。例如把&quot;123&quot;字符串转换为123数字。 <br/>这些都是常用的功能，如果你有兴趣可以试试。其实有人已经实现了，看看Extended STL string。如果你想偷懒，下载一个头文件就可以用，有了它确实方便了很多。要是有人能提供一个支持正则表达式的string，我会非常乐意用。 <br/><br/>4 string 建议 <br/>使用string 的方便性就不用再说了，这里要重点强调的是string的安全性。 <br/>string并不是万能的，如果你在一个大工程中需要频繁处理字符串，而且有可能是多线程，那么你一定要慎重(当然，在多线程下你使用任何STL容器都要慎重)。 <br/>string的实现和效率并不一定是你想象的那样，如果你对大量的字符串操作，而且特别关心其效率，那么你有两个选择，首先，你可以看看你使用的STL版本中string实现的源码；另一选择是你自己写一个只提供你需要的功能的类。 <br/>string的c_str()函数是用来得到C语言风格的字符串，其返回的指针不能修改其空间。而且在下一次使用时重新调用获得新的指针。 <br/>string的data()函数返回的字符串指针不会以&#039;&#92;0&#039;结束，千万不可忽视。 <br/>尽量去使用操作符，这样可以让程序更加易懂（特别是那些脚本程序员也可以看懂） <br/>5 小结 <br/>难怪有人说：<br/>string 使用方便功能强，我们一直用它！ <br/><br/>6 附录 <br/>string 函数列表 函数名 描述 <br/>begin 得到指向字符串开头的Iterator <br/>end 得到指向字符串结尾的Iterator <br/>rbegin 得到指向反向字符串开头的Iterator <br/>rend 得到指向反向字符串结尾的Iterator <br/>size 得到字符串的大小 <br/>length 和size函数功能相同 <br/>max_size 字符串可能的最大大小 <br/>capacity 在不重新分配内存的情况下，字符串可能的大小 <br/>empty 判断是否为空 <br/>operator[] 取第几个元素，相当于数组 <br/>c_str 取得C风格的const char* 字符串 <br/>data 取得字符串内容地址 <br/>operator= 赋值操作符 <br/>reserve 预留空间 <br/>swap 交换函数 <br/>insert 插入字符 <br/>append 追加字符 <br/>push_back 追加字符 <br/>operator+= += 操作符 <br/>erase 删除字符串 <br/>clear 清空字符容器中所有内容 <br/>resize 重新分配空间 <br/>assign 和赋值操作符一样 <br/>replace 替代 <br/>copy 字符串到空间 <br/>find 查找 <br/>rfind 反向查找 <br/>find_first_of 查找包含子串中的任何字符，返回第一个位置 <br/>find_first_not_of 查找不包含子串中的任何字符，返回第一个位置 <br/>find_last_of 查找包含子串中的任何字符，返回最后一个位置 <br/>find_last_not_of 查找不包含子串中的任何字符，返回最后一个位置 <br/>substr 得到字串 <br/>compare 比较字符串 <br/>operator+ 字符串链接 <br/>operator== 判断是否相等 <br/>operator!= 判断是否不等于 <br/>operator&lt; 判断是否小于 <br/>operator&gt;&gt; 从输入流中读入字符串 <br/>operator&lt;&lt; 字符串写入输出流 <br/>getline 从输入流中读入一行<br/>
]]>
</description>
</item><item>
<link>http://www.jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] C++ string 详解]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>