当前位置:C++技术网 > 资讯 > string系列:2 字符串string声明和string初始化

string系列:2 字符串string声明和string初始化

更新时间:2015-06-23 14:59:34浏览次数:1+次

    string类使用需要包含string头文件,如#include<string>。
    1.默认声明初始化

string defstr;

     这样就声明并初始化了一个默认的空string对象。通过defstr.data()可以返回对象内部字符数组的常量指针。

    使用如:

const char * pconstchar = defstr.data();

    不能通过pconstchar 修改内部的字符数组,因为是常量指针,这样的指针不具有修改变量值的特性,因此可以保护内部的数据不会被修改。如果有特殊需求,可以将常量指针转化成变量指针来操作数据,如

char * p = (char*)pstr;

     除非你很清楚内部原理,否则不建议这么做,这样会导致问题,下面就来讨论会引起的问题。
    默认构造函数实例化的string,在内部分配了一块初始大小的内存,大小不确定,可以通过defstr.capacity()来获得,以元素数来确定大小。如果返回的是15,表明这一块内存可以存放15个字符。这是表明的这块内存的容量。如果超出,会重新分配内存以容纳更多的字符。容量不表示字符数,要获取字符数,通过defstr.size()获取。如果给defstr赋值,则会自动扩大size的大小,只要不超出大小就不会引起分配。如果字符填满了这块内存,C++就会自动扩展大小,因此你不用担心会有不够装。但是这里需要注意一个问题,正式因为会重新分配内存,可能会在后续的内存块分配(紧接着的内存块可以用)或者再另外一个地方分配一个内存块,因此返回的内部字符数组的地址就发生变化了。这个时候就不能使用之前的指针访问新分配后的内存地址。所以前面说的不建议转换为变量指针去修改就是这个原因。因为默认构造函数创建的是空字符串,它保证了第一个元素是可用的,对第一个元素操作还不会引起内存重分配,而如果操作了第一个之后的元素就会引起内存重分配,这样这个变量指针就不再指向defstr内部的字符数组了,如果操作可能就出现内存访问错误。所以,要对字符串进行操作,直接对defstr对象进行赋值修改等操作就可以了,如果要得到一个C风格字符串即以空字符作为结束标志的字符串,则使用defstr.c_str();当然返回的还是常量指针,不能通过这个指针修改内部数据。
    注意:data()和c_str()都返回常量字符指针,都是指向内部字符串的第一个元素。区别就是,data()只保证字符都存在,不一定有空字符在结尾,而c_str()则是一个以空字符结尾的字符串,所以通常我们是用后面的返回C风格字符串。还要注意一个问题,string对象内部实现可能是数组,也可能不是数组,这个需要注意,返回的指向内部字符串的指针可能是指向内部原始的字符串也可能是一个副本,这都和具体实现相关。但是我们只要通过string提供的成员函数来操作就不用担心内部实现的问题,都可以保证正确的结果。
   
    2.使用数组声明初始化

string arrstr("123456");
cout<<arrstr<<endl;
     这里说明一下,arrstr.size()和arrstr.length()作用相同。


    3.使用部分数组声明初始化

string arrstr("123456",3);//从字符串索引为0开始的3个字符,结果为“123”
cout<<arrstr<<endl;

 

    4.复制声明初始化
    这种方法使用已有的string对象来创建一个新的string对象,可以对已有的字符串的一部分或者全部字符来初始化新字符串对象。
    如:

string oldstr("123456");
string newstr(oldstr);//复制整个旧的字符串来创建新字符串
string newstr(oldstr,4);//从索引为4处开始复制直到原字符串结尾,newstr为56两个字符
string newstr(oldstr,4,1);//从索引为4处开始复制直到原字符串结尾,newstr为5一个字符

 

    5.使用若干个相同的字符声明初始化

string newstr(10,'a');//newstr的值为“aaaaaaaaaa”10个a组成的字符串。

   

    6.使用STL容器来声明初始化
    STL容器的迭代器,是一种广义的指针,就是说,能标志一个位置的都称为迭代器。所以,数组的地址可以作为迭代器,用于通常的数组。可以用数组来初始化string对象。

char ar[]={'a','b','c','d'};
string newstr(ar+1,ar+3);//结果为“bc”,因为区间不包括最后一个,复制的字符位置为1,2
cout<<newstr<<endl;

    直接让数组地址作为迭代器,迭代器就是指示区间的一个标志。
vector<char> v;//要包含头文件#include <vector>
v.push_back('a');//加入一个元素
v.push_back('b');
v.push_back('c');
v.push_back('d');
vector<char>::iterator it=v.begin();//迭代器声明初始化,指向第一个元素
string newstr(it,it+2);//由迭代器指向位置为0,1,newstr结果为“ab”
cout<<newstr<<endl;

     string对象的声明并初始化基本就是这样。