C++ string详解

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*/



Liang
Liang
cccccccccc

除了上面之外,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 Liang
Hi
Hi
Mark
Mark
Mark Liang
Mark 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 SimonS
Hi, 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 45
std::stoi("3.14159") is 3
std::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
`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值