`
javababy1
  • 浏览: 1171529 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

STL--string用法(2)

 
阅读更多

    1. 系统遇到"+"号,发现有一项是string 对象。
    2. 系统把另一项转化为一个临时 string 对象。
    3. 执行 operator + 操作,返回新的临时string 对象。
    4. 如果又发现"+"号,继续第一步操作。
  • 1 string 使用

    其实,string并不是一个单独的容器,只是basic_string 模板类的一个typedef 而已,相对应的还有wstring, 你在string 头文件中你会发现下面的代码:

    extern "C++" {

    typedef basic_string <char> string;

    typedef basic_string <wchar_t> wstring;

    } // extern "C++"

    由于只是解释string的用法,如果没有特殊的说明,本文并不区分string 和 basic_string的区别。

    string 其实相当于一个保存字符的序列容器,因此除了有字符串的一些常用操作以外,还有包含了所有的序列容器的操作。字符串的常用操作包括:增加、删除、修改、查找比较、链接、输入、输出等。详细函数列表参看附录。不要害怕这么多函数,其实有许多是序列容器带有的,平时不一定用的上。

    如果你要想了解所有函数的详细用法,你需要查看basic_string,或者下载STL编程手册。这里通过实例介绍一些常用函数。

    1.1 充分使用string 操作符

    string 重载了许多操作符,包括 +, +=, <, =, , [], <<, >>等,正式这些操作符,对字符串操作非常方便。先看看下面这个例子:tt.cpp(例程2)

    #include <string>

    #include <iostream>

    using namespace std;

    int main(){

    string strinfo="Please input your name:";

    cout << strinfo ;

    cin >> strinfo;

    if( strinfo == "winter" )

    cout << "you are winter!"<<endl;

    else if( strinfo != "wende" )

    cout << "you are not wende!"<<endl;

    else if( strinfo < "winter")

    cout << "your name should be ahead of winter"<<endl;

    else

    cout << "your name should be after of winter"<<endl;

    strinfo += " , Welcome to China!";

    cout << strinfo<<endl;

    cout <<"Your name is :"<<endl;

    string strtmp = "How are you? " + strinfo;

    for(int i = 0 ; i < strtmp.size(); i ++)

    cout<<strtmp[i];

    return 0;

    }

    下面是程序的输出

    -bash-2.05b$ make tt

    c++ -O -pipe -march=pentiumpro tt.cpp -o tt

    -bash-2.05b$ ./tt

    Please input your name:Hero

    you are not wende!

    Hero , Welcome to China!

    How are you? Hero , Welcome to China!

    有了这些操作符,在STL中仿函数都可以直接使用string作为参数,例如 less, great, equal_to 等,因此在把string作为参数传递的时候,它的使用和int 或者float等已经没有什么区别了。例如,你可以使用:

    map<string, int> mymap;

    //以上默认使用了 less<string>

    有了 operator + 以后,你可以直接连加,例如:

    string strinfo="Winter";

    string strlast="Hello " + strinfo + "!";

    //你还可以这样:

    string strtest="Hello " + strinfo + " Welcome" + " to China" + " !";

    看见其中的特点了吗?只要你的等式里面有一个 string 对象,你就可以一直连续"+",但有一点需要保证的是,在开始的两项中,必须有一项是 string 对象。其原理很简单:

    由于这个等式是由左到右开始检测执行,如果开始两项都是const char* ,程序自己并没有定义两个const char* 的加法,编译的时候肯定就有问题了。

    有了操作符以后,assign(), append(), compare(), at()等函数,除非有一些特殊的需求时,一般是用不上。当然at()函数还有一个功能,那就是检查下标是否合法,如果是使用:

    string str="winter";

    //下面一行有可能会引起程序中断错误

    str[100]='!';

    //下面会抛出异常:throws: out_of_range

    cout<<str.at(100)<<endl;

    了解了吗?如果你希望效率高,还是使用[]来访问,如果你希望稳定性好,最好使用at()来访问。

    1.2 眼花缭乱的string find 函数

    由于查找是使用最为频繁的功能之一,string 提供了非常丰富的查找函数。其列表如下:

    函数名

    描述

    find

    查找

    rfind

    反向查找

    find_first_of

    查找包含子串中的任何字符,返回第一个位置

    find_first_not_of

    查找不包含子串中的任何字符,返回第一个位置

    find_last_of

    查找包含子串中的任何字符,返回最后一个位置

    find_last_not_of

    查找不包含子串中的任何字符,返回最后一个位置

    以上函数都是被重载了4次,以下是以find_first_of 函数为例说明他们的参数,其他函数和其参数一样,也就是说总共有24个函数 :

    size_type find_first_of(const basic_string& s, size_type pos = 0)

    size_type find_first_of(const charT* s, size_type pos, size_type n)

    size_type find_first_of(const charT* s, size_type pos = 0)

    size_type find_first_of(charT c, size_type pos = 0)

    所有的查找函数都返回一个size_type类型,这个返回值一般都是所找到字符串的位置,如果没有找到,则返回string::npos。有一点需要特别注意,所有和string::npos的比较一定要用string::size_type来使用,不要直接使用int 或者unsigned int等类型。其实string::npos表示的是-1, 看看头文件:

    template <class _CharT, class _Traits, class _Alloc>

    const basic_string<_CharT,_Traits,_Alloc>::size_type

    basic_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 如何实现:

    #include <string>

    #include <iostream>

    using namespace std;

    int main(){

    string strinfo=" //*---Hello Word!......------";

    string strset="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    int first = strinfo.find_first_of(strset);

    if(first == string::npos) {

    cout<<"not find any characters"<<endl;

    return -1;

    }

    int last = strinfo.find_last_of(strset);

    if(last == string::npos) {

    cout<<"not find any characters"<<endl;

    return -1;

    }

    cout << strinfo.substr(first, last - first + 1)<<endl;

    return 0;

    }

    这里把所有的英文字母大小写作为了需要查找的字符集,先查找第一个英文字母的位置,然后查找最后一个英文字母的位置,然后用substr 来的到中间的一部分,用于输出结果。下面就是其结果:

    Hello Word

    前面的符号和后面的符号都没有了。像这种用法可以用来查找分隔符,从而把一个连续的字符串分割成为几部分,达到 shell 命令中的 awk 的用法。特别是当分隔符有多个的时候,可以一次指定。例如有这样的需求:

    张三|3456123, 湖南

    李四,4564234| 湖北

    王小二, 4433253|北京

    ...

    我们需要以 "|" ","为分隔符,同时又要过滤空格,把每行分成相应的字段。可以作为你的一个家庭作业来试试,要求代码简洁

    1.3 string insert, replace, erase

    了解了string 的操作符,查找函数和substr,其实就已经了解了string的80%的操作了。insert函数, replace函数和erase函数在使用起来相对简单。下面以一个例子来说明其应用。

    string只是提供了按照位置和区间的replace函数,而不能用一个string字串来替换指定string中的另一个字串。这里写一个函数来实现这个功能:

    void string_replace(string & strBig, const string & strsrc, const string &strdst) {

    string::size_type pos=0;

    string::size_type srclen=strsrc.size();

    string::size_type dstlen=strdst.size();

    while( (pos=strBig.find(strsrc, pos)) != string::npos){

    strBig.replace(pos, srclen, strdst);

    pos += dstlen;

    }

    }

    看看如何调用:

    #include <string>

    #include <iostream>

    using namespace std;

    int main() {

    string strinfo="This is Winter, Winter is a programmer. Do you know Winter?";

    cout<<"Orign string is :/n"<<strinfo<<endl;

    string_replace(strinfo, "Winter", "wende");

    cout<<"After replace Winter with wende, the string is :/n"<<strinfo<<endl;

    return 0;

    }

    其输出结果:

    Orign string is :

    This is Winter, Winter is a programmer. Do you know Winter?

    After replace Winter with wende, the string is :

    This is wende, wende is a programmer. Do you know wende?

    如果不用replace函数,则可以使用erase和insert来替换,也能实现string_replace函数的功能:

    void string_replace(string & strBig, const string & strsrc, const string &strdst) {

    string::size_type pos=0;

    string::size_type srclen=strsrc.size();

    string::size_type dstlen=strdst.size();

    while( (pos=strBig.find(strsrc, pos)) != string::npos){

    strBig.erase(pos, srclen);

    strBig.insert(pos, strdst);

    pos += dstlen;

    }

    }

    当然,这种方法没有使用replace来得直接。

    源文档 <http://blog.chinaunix.net/u2/87718/showart_1834935.html>

分享到:
评论

相关推荐

    STL-基础数据类型的基本用法

    STL-ARR,arry, file,list,map,priority_queue,set,share_ptr,stack,string,template,等基本数据类型

    STL中的string介绍

    STL中的string介绍,以及如何合起来使用的方法

    cPP-string--.rar_c string_doc_string stl

    c++中的string用法(一) .doc 详细介绍了 stl string 在C++中的使用方法

    stl几个用法,c++stl 学习

    stl几个(set map vector string)用法,c++ stl 学习资料

    c++ STL string学习资料

    c++ STL string学习资料 包括string 的所有用法,以及注意点 以及国际标准等

    leetcode2sumc-Cpp-STL-Quick-Help:它包含C++STL用法和快速帮助以及易于理解的注释和示例

    用法和快速帮助以及易于理解的注释和示例(复制+粘贴以使用)。 我在解决不同类型的 Leetcode 问题时学到了这些。 我将使用“int、string 等”来方便而不是像对、结构等复杂的实体 :winking_face: . 你可以用任何...

    STL入门快速入门教程-----学习C++

    STL重要部分,包含了许多数据结构,有vector(动态增加的数组),queue(队列),stack(堆栈)……甚至也包括string,它也可以看做为一种容器,并且适用所有的容器可用的方法。 7:算法(algorithms)部分。STL重要...

    标准库STL_第1节_顺序容器

    详细介绍标准库STL中的容器:vector、list、forward_list、deque、string、array,讲解常用函数,并举例说明常见的用法和原理。

    effective stl stl 技巧

    条款13:尽量使用vector和string来代替动态分配的数组 条款14:使用reserve来避免不必要的重新分配 条款15:小心string实现的多样性 条款16:如何将vector和string的数据传给传统的API 条款17:使用“交换技巧...

    craster:从STL 3D模型创建PNG缩略图

    接受STL,OBJ和3DS文件,并返回360°旋转的PNG Sprite图片。 用法 $ craster --help Usage: craster [OPTIONS] [ARGS] Options: -u, --url STRING URL of the 3D model --path STRING Path of the 3D model -i,...

    STL容器使用代码

    c++ STL容器使用代码,方便学习 vector string deque queue list set map multiset multimap 容器的API使用方法等

    STL基础详解

    STL基础详解,其中包含了String的用法等

    Effective STL(中文)

    在删除选项中仔细选择 条款10:注意分配器的协定和约束 条款11:理解自定义分配器的正确用法 条款12:对STL容器线程安全性的期待现实一些 vector和string 条款13:尽量使用vector和string来代替动态...

    C++实现string存取二进制数据的方法

    主要介绍了C++实现string存取二进制数据的方法,针对STL中string的用法进行了较为详细的分析,需要的朋友可以参考下

    C++STL程序员开发指南【可搜索+可编辑】

    2-1-2 string 类....................................................... 48 4849 ..... .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. •. .• .. .. .. .. .. .. .. .. .....

    C++中STL的基本用法总结

    C++的STL string vector list stack queue set map 等常用的容器使用

    CString,string,char*之间的转换

    string是使用STL时必不可少的类型,所以是做工程时必须熟练掌握的;char*是从学习C语言开始就已经和我们形影不离的了,有许多API都是以char*作为参数输入的。所以熟练掌握三者之间的转换十分必要。 以下我用简单的...

    自己写的ac自动机,STL实现

    相当给力,头文件中附带了简单的使用方法,使用istream当接口,因此你可以传入stringstream或fstream,甚至可以自己派生istream再传入,支持全文查找和增量查找两种模式,有问题可以联系我

    STL list链表的用法详细解析

    0 前言1 定义一个list2 使用list的成员函数push_back和push_front插入一个元素到list中3 list的成员函数empty()4 用for循环来处理list中的元素5 用STL的通用算法for_each来处理list中的元素6 用STL的通用算法count_...

    浅谈c++中的stl中的map用法详解

    Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据处理能力,由于这个特性,它完成有可能在我们处理一对一数据的时候,在编程...

Global site tag (gtag.js) - Google Analytics