C++ string详解

来源:互联网 发布:windows禁止icmp 编辑:程序博客网 时间:2024/06/08 07:36

C++中被认为不太好的一个特点就是兼容C,兼容C需要付出很沉重的代价,不过这其中部分原因有当时的局限性。C风格的字符串设计不是一个比较好的方式,特别是结尾的’\0’结束符。所以在此C++ STL中设计了一种string类型来代替C风格的字符串,比起C风格的字符串。C++中的string更安全,也更加好用。
其实string并不是一个单独的容器,是basic_string类的一个typedef,在string头文件中有这样的一个定义。相应地,还有宽字符集的wstring

                   typedef std::basic_string<char> std::string                    typedef std::basic_string<wchar_t> std::string

现在讲一下string的一些基本用法。

string的构造

string s1;          //默初始化,s1为一个空串string s2(s1)       //s2是s1的副本string s3=s1;       //same as s2(s1)string s4("Liang"); //s3位字面值"Liang"的副本string s5="Liang";  //same as s4("Liang")string s6(n,'c');   //把s6初始化为n个连续字符c的集合   

下面是一个简单示例:

#include <iostream>#include <string>using namespace std;int main(){    string s1;              string s2(s1);        string s3=s1;          string s4("Liang");     string s5="Liang";      string s6(10,'c');    cout<<s1<<endl<<s2<<endl<<s3<<endl;    cout<<s4<<endl<<s5<<endl<<s6<<endl;}/*Output*/LiangLiangcccccccccc

除了上面之外,string还有另外三种构造函数:

string s(cp,n)      //s是从cp指向的数组中前n个字符的拷贝,n至少包含n个字符string s(s2,pos2)   //s是string s2从下标pos2开始的字符的拷贝,如果pos2>s2.size(),则构造函数行为为定义string s(s2,pos2,len2) //s是string s2从pos2开始len2个字符的拷贝,同样,如果pos2>s2.size()则构//造函数行为未定义,不管len2的大小是多少,构造函数最多拷贝size()-pos2个字符,不会抛出异常.

有点啰嗦是吧,没事,我举个例子。

#include <iostream>#incldue <string>using namespace std;int main(void){const char *cp="Hello Mark Liang";char noNull[]={'H','i'};    string s1(cp);          //s1=="Hello Mark Liang"    string s2(noNull,2);    //copy two character from noNull s2=="Hi"    string s3(noNull);      //undefined behavior noNull不是以空字符结尾    string s4(cp+6,5);      //copy char from cp[6] so s4=="Mark "    string s5(s1,6,5);      //copy char from s1[6] so s5=="Mark "    string s6(s1,6);        //copy from s1[6] util the end of s1 so s6=="Mark Liang"    string s7(s1,6,20);     //right s7 same as s6 so s7=="Mark Liang"//  string s8(s1,20);       //error throw a out_of_range exception  }  运行结果:Hello Mark LiangHiHiMarkMarkMark LiangMark Liang

当我们从const char *类型创建string时,要求指针指向的数组必须以空字符结尾, 拷贝操作直到遇到空字符。

string类型的比较操作

有了运算符的重载,string的比较和连接变得很方便。可以对string进行+,+=,==,>=,<=,!=这些操作。
看下面的例子

#include <iostream>#include <string>using namespace std;int main(void){string name="Mark";    if(name=="SimonS")        cout<<"You are SimonS"<<endl;    else if(name!="SimonS")        cout<<"You are not SimonS"<<endl;    else if(name<"SimonS")        cout<<"Your name should be after of SimonS"<<endl;    else if(name>"SimonS")        cout<<"Your name should be ahead of SimonS"<<endl;    name+=", Do you know SimonS? a ACMer, retired";    string info="Hi, "+name;    for(auto temp=info.begin();temp!=info.end();temp++)        cout<<*temp;    return 0;}/**output**/You are not SimonSHi, Mark Do you know SimonS? A ACMer, retired

string可以通过”+”运算符把两个字符串加起来,不过也有一个前提,”+”号两边必须有一个是string类型。例如:

const char * str1="Hello Mark";const char * str2=" Liang";string info=str1+str2;  //error

上述例子将会编译出错。因为只有左右两边有一个是string类型,编译器就会把其中的C风格字符串转换为string对象。而如果两个都不是string类型,则就无法转换。
除此之外,string中还定义了compare()函数,compar函数有6个版本。根据我们是比较两个string,一个字符串数组与string,参数各有不同。都可以比较整个或一部分字符串。

string类型的查找

1:substr()函数

substr()返回一个string,它是一个原始string的一部分或全部。它支持以下几种操作:

string s="Mark Liang";string s2=s.substr(0,4);  //s2="Mark"string s3=s.substr(5);    //s3="Liang"string s4=s.substr(5,20); //s4="Liang"string s5=s.substr(20);   //try a out_of_range error

2:find()操作

string类提供了6个不同的搜索函数,其中每个函数都有4个重载版本。如果查找成功,则返回一个string::size_type 值,表示匹配发生位置的下标。如果查找失败,则返回一个string::npos 的static成员,标准库将npos定义为一个const string::size_type类型。6个函数分别如下:

s.find(args)            //查找s中args第一次出现的位置s.rfind(args)           //查找s中args最后一次出现的位置s.find_first_of(args)   //在s中查找args中任何一个字符第一次出现的位置s.find_last_of(args)    //在s中查找ars中任何一个字符最后出现的位置s.find_first_not_of(args)//查找第一个不在args中的字符s.find_last_not_of(args) //查找最后一个不在args中的字符

下面有一个例子作为示范,把一个string中的某段字符串替换为指定的字符串

#include <iostream>#include <string>using namespace std;void replaceString(string &str,const string &src,const string &dst){    string::size_type pos=0;    while((pos=str.find(src,pos))!=string::npos){        str.replace(pos,src.size(),dst);        pos+=dst.size();    }}int main(int argc,char **argv){    string info="Hi,Do you know Mark? A ACMer from HangZhou.Mark is very smart!";    string dst="SimonS";    cout<<"Before replace:"<<info<<endl;    replaceString(info,"Mark",dst);    cout<<"After replace:"<<info<<endl;    return 0;}/****Output****/Before replace:Hi,Do you know Mark? A ACMer from HangZhou.Mark is very smart!After replace:Hi,Do you know SimonS? A ACMer from HangZhou.SimonS is very smart!

数值转换

C++11标准的引入,让C++变得更加完美。据C++之父,Bjarne Stroustrup也曾说,C++11让他感觉已经不是C++了,是一门新的语言。当然了,string中也增加了类似Java中的toString()方法,stoi(),stod()等从字符串到数值和to_string(),从数值到字符串的转换函数。

#include <iostream>#include <string>int main(){    std::string str1 = "45";    std::string str2 = "3.14159";    std::string str3 = "31337 with words";    std::string str4 = "words and 2";    int myint1 = std::stoi(str1);    int myint2 = std::stoi(str2);    int myint3 = std::stoi(str3);    // error: 'std::invalid_argument'    // int myint4 = std::stoi(str4);    std::cout << "std::stoi(\"" << str1 << "\") is " << myint1 << '\n';    std::cout << "std::stoi(\"" << str2 << "\") is " << myint2 << '\n';    std::cout << "std::stoi(\"" << str3 << "\") is " << myint3 << '\n';    //std::cout << "std::stoi(\"" << str4 << "\") is " << myint4 << '\n';}/****OutPut****/std::stoi("45") is 45std::stoi("3.14159") is 3std::stoi("31337 with words") is 31337

对sring的介绍就到这里,大家如果想更详细的了解,请访问:
http://en.cppreference.com/w
参考资料:
https://www.byvoid.com/blog/cpp-string
http://en.cppreference.com/w/cpp/string/basic_string
`

0 0
原创粉丝点击