zoukankan      html  css  js  c++  java
  • 17.C++-string字符串类(详解)

    C++字符串string类

    在C语言里,字符串是用字符数组来表示的,而对于应用层而言,会经常用到字符串,而继续使用字符数组,就使得效率非常低.

    所以在C++标准库里,通过类string从新自定义了字符串。

    头文件: #include <string>

    • string直接支持字符串连接
    • string直接支持字符串的大小比较
    • string直接支持子串查找和提取
    • string直接支持字符串的插入和替换
    • string同时具备字符串数组的灵活性,可以通过[ ]重载操作符来访问每个字符。

    字符串数组和string对象尽量不要混合使用,会带来意想不到的问题

    例如,通过字符串数组赋值给string对象:

      string str;
      char s[]="12345";
    
      str.reserve(5);
    
      for(int i=0;i<5;i++)
      str[i]=s[i];
    
      cout<<"str:"<<str<<endl;
      cout<<"length():"<<str.length()<<endl;

    打印运行:

    str:
    length():0

    这是因为,使用for循环拷贝,仅仅改变了str的串内容,并没有改变str的length长度.

    string类常用的构造函数有:

    string str;        //生成一个空字符串
    
    string str ("ABC")  //等价于 str="ABC"
    string str ("ABC", strlen) // 将"ABC"存到str里,最多存储前strlen个字节 string s("ABC",stridx,strlen) //将"ABC"的stridx位置,做为字符串开头,存到str里.且最多存储strlen个字节. string s(strlen, 'A') //存储strlen个'A'到str里

    string类常用的成员函数有:

    str1.assign("ABC");        //清空string串,然后设置string串为"ABC"
    
    str1.length();                 //获取字符串长度
    
    str1.size();            //获取字符串数量,等价于length()
    
    str1.capacity();          //获取容量,容量包含了当前string里不必增加内存就能使用的字符数
    
    str1.resize(10);           //表示设置当前string里的串大小,若设置大小大于当前串长度,则用字符来填充多余的.
    str1.resize(10,char c);     //设置串大小,若设置大小大于当前串长度,则用字符c来填充多余的
    
    str1.reserve(10);         //设置string里的串容量,不会填充数据.
    str1.swap(str2);              //替换str1 和 str2 的字符串
    
    str1.puch_back ('A');      //在str1末尾添加一个'A'字符,参数必须是字符形式
     
    str1.append ("ABC");       //在str1末尾添加一个"ABC"字符串,参数必须是字符串形式
    
    str1.insert (2,"ABC");       //在str1的下标为2的位置,插入"ABC"
    
    str1.erase(2);             //删除下标为2的位置,比如: "ABCD" --> "AB"
    
    str1.erase(2,1);              //从下标为2的位置删除1个,比如: "ABCD"  --> "ABD"
    
    str1.clear();              //删除所有
    
    str1.replace(2,4, "ABCD"); //从下标为2的位置,替换4个字节,为"ABCD"
    
    str1.empty();            //判断为空, 为空返回true
    

      

    /*assign() :赋值函数 ,里面会重新释放分配字符串内存 */
    str1.assign("HELLO");                   //str1="HELLO"
    str1.assign("HELLO", 4);                //str1="HELL" ,只保留4个字符
    str1.assign("HELLO", 2, 3);             //str1="LLO"    ,从位置2开始,只保留3个字符
    str1.assign(5, 'c');                    //str1="CCCCC"             //按字符赋值

     

    const char* c_str();   

    返回一个常量C字符串, 内容与本string串相同. 

    注意:当本string的内容改变,或被析构后,返回的字符串也不会被改变,因为返回的字符串是从新通过new char[]出来.

    参考下面代码,可以发现返回的C字符串地址和string里的字符串地址完全不同:

    string* str = new string("ASD"); //str="ASD" 
    const char* c = str->c_str(); 
    
    cout
    <<c<<endl; //打印 : "ASD" printf("&c[0]=%p,&str[0]=%p ",&c[0],&str[0]); //打印:c=0x94bf024,&str[0]=0x94bf008 str->append("dd"); //str="ASDdd"   cout<<c<<endl; //打印 : "ASD"
    delete str; //调用析构
    cout<<c<<endl; //打印 : "ASD"

    反转相关(位于头文件<algorithm>)

    string str("hello");
    
    reverse(str.begin(),str.end());
    
    cout<< str <<endl;              //反转自身字符串,打印olleh

    查找相关:

    string str("ABCDEFGABCD");                      //11个字符
    int n;
    /*查找成功返回位置,查找失败,则n等于-1*/ /*find():从头查找某个字符串*/ n= str.find('A'); //查找"A",n=0; n= str.find("AB"); //查找"AB",n=0; n= str.find("BC",1); //从位置1处,查找"BC",n=1; n= str.find("CDEfg",1,3); //从位置1处,查找"CDEfg"的前3个字符,等价于str.find("CDE",1),n=2; /*rfind():反向(reverse)查找,从末尾处开始,向前查找*/ n= str.rfind("CD"); //从位置10开始向前查找,n=9 n= str.rfind("CD",5); //从位置5开始向前查找,n=2 n= str.rfind("CDEfg",5,3); //等价于str.rfind("CDE",5); ,所以n=2 /* find_first_of ():查找str里是否包含有子串中任何一个字符*/ n= str.find_first_of("abcDefg"); //由于str位置3是'D',等于"abcDefg"的'D',所以n=3 n= str.find_first_of("abcDefg",1,4); //等价于str. find_first_of ("abcD",1); 所以n=3 /* find_last_of ():末尾查找, 从末尾处开始,向前查找是否包含有子串中任何一个字符*/ n= str.find_last_of("abcDefg"); //由于str末尾位置10是'D',所以n=10 n= str.find_last_of("abcDefg",5,4); //等价于str. find_last_of ("abcD",5); 所以n=3 /* find_first_not_of ():匹配子串任何一个字符,若某个字符不相等则返回str处的位置,全相等返回-1*/ n= str.find_last_not_of("ABC"); //由于str位置3'D',在子串里没有,所以 n=3 n= str.find_last_not_of("aABDC"); //由于str位置4 'F',在子串里没有,所以 n=4 n= str.find_last_not_of("aBDC"); //由于str位置0 'A',在子串里没有,所以 n=0
    /* find_last_not_of ():反向匹配子串任何一个字符,若某个字符不相等则返回str处的位置,全相等返回-1*/ n= str.find_last_not_of("aBDC"); //由于str位置7'A',在子串里没有,所以 n=7

    拷贝相关:

    str2=str1.substr(2);        //提取子串,提取出str1的下标为2到末尾,给str2
    
    str2=str1.substr(2,3);     //提取子串,从 str1的下标为2开始,提取3个字节给str2
    
    const char *s1= str.data();   //将string类转为字符串数组,返回给s1
    
    char *s=new char[10]; str.copy(s,count,pos); //将str里的pos位置开始,拷贝count个字符,存到s里.

    实例1,通过string类实现字符串循环右移功能

    比如:  "abcdefg" 循环右移3位等到: "efgabcd"

    代码如下:

    #include <iostream>
    #include <string>
    #include <sstream>
    
    using namespace std;
    
    string operator >>(const string& str,int n)
    {
           string ret;
           n %= str.length();
    
           ret=str.substr(str.length()-n);              //找到右移的字符串
           ret+=str.substr(0,str.length()-n);  
    
           return ret;
    }
    
    int main()
    {     
           string str="abcdefg";
           string ret= str>>3 ;
           cout<<ret<<endl;
    
           return 0;
    }

    实例2,通过string类实现字符串反转

    比如: "we;tonight;you" -> "ew;thginot;uoy"

    代码如下:

    #include <iostream>
    #include <string>
    #include <sstream>
    #include <algorithm>
    using namespace std;
    
    string reverse_func(const string& str)
    {
           int end;
           int start=0;
           int len;
           string ret="";
           string tmp;
    
          while(1)
          {
             end=str.find(';',start);
    
             if(end== -1)          //没找到;
            {
             len=str.length()-start;
             tmp=str.substr(start,len);
    
             reverse(tmp.begin(),tmp.end());   //反转字符串
    
             ret+=tmp;
    
             return ret;
            }
            else               //找到;
            {
             len=end-start;
             tmp=str.substr(start,len);
    
             reverse(tmp.begin(),tmp.end());     //反转字符串
    
             ret+=tmp+';';
             start=end+1;
            }
    
         }   
    
    }
    
    int main()
    {     
           string str("we;tonight;you");
    
           string ret=reverse_func(str);
    
           cout<< ret<<endl;             
    
           return 0;
    }
    

      

    字符串与数字的转换

    以前,在C里,当我们想获取字符串里的数字时,一般都是通过strtoul()或者sscanf()获取

    在C++标准库里,也提供字符串与数字的转换.位于<sstream>头文件.

    同时需要用到两个类:

    istringstream                //字符串输入流
    
    ostringstream              //字符串输出流

    将string 字符串 ->数字,使用方法如下

    istringstream iss ("123.5");    //定义对象iss,初始化为"123.5" ,  
    //等价于:
    //istringstream iss;
    //iss.str("123.5");                 //设置对象iss为"123.5" ,
    
    double num;
    
     if(iss>>num)                 //通过调用iss.operator >>(num), 将"123.5"转为数字,并返回bool类型变量
    {
        cout<<num << endl;
    }

    也可以通过临时对象转换,这样写:

    string str="123.5";
    
    double num;
    
    if(istringstream(str)>>num)        //通过临时对象,来将str转为数字
      cout<<num<<endl;

    或者将第3行,写为宏:

    #define TO_NUM(str,num)     (istringstream(str)>>num)
    //也可以写成模板函数
    

      

    将数字->string 字符串,使用方法如下

    ostringstream oss;
    oss <<123.5;                   //相当于调用: oss.str("123.5");
    string str= oss.str() ;
    cout<<str << endl;

    也可以通过宏,这样写:

    #define TO_STRING(num)     ( ((ostringstream&)(ostringstream()<<num)).str() )
    
    double num=123.5;
    string str= TO_STRING(123.5);
    cout<<num<<endl;
    

      

  • 相关阅读:
    1104 Sum of Number Segments (20 分)(数学问题)
    1092 To Buy or Not to Buy (20 分)(hash散列)
    1082 Read Number in Chinese (25 分)(字符串处理)【背】
    1105 Spiral Matrix (25 分)(模拟)
    初识网络安全及搭建网站(内网)
    HTML5开发者需要了解的技巧和工具汇总(转)
    native+web开发模式之web前端经验分享
    移动平台3G手机网站前端开发布局技巧汇总(转)
    Asp.net 中图片存储数据库以及页面读取显示通用方法详解附源码下载
    使用H3Viewer来查看VS2010的帮助文档
  • 原文地址:https://www.cnblogs.com/lifexy/p/8642163.html
Copyright © 2011-2022 走看看