对于C语言中的字符串,我们只能使用char类型数组保存,并且是以'\0'结尾的.
成都创新互联公司主营德令哈网站建设的网络公司,主营网站建设方案,成都app开发,德令哈h5小程序定制开发搭建,德令哈网站营销推广欢迎德令哈等地区企业咨询操作起来非常不方便而且底层空间需要用户自己访问,非常造成容易越界访问.
这个时候,C++的STL中的string类就很好解决了这些.
目录
string的使用
1.string类对象的常见构造
2. string类对象的容量操作
3. string类对象的访问及遍历操作
4. string类对象的修改操作
5.string类非成员函数
string的使用主要是使用一些接口,下面将列出一些常用的接口使用.
1.string类对象的常见构造当我们用string初始化对象时,可采用以下方法:
string() 构造空的string类对象,即空字符串
string(const char* s) 用C-string来构造string类对象
string(size_t n,char c) string类对象中包含n个字符c
string(const string& s) 拷贝构造函数
看下列代码
void Teststring()
{
string s1; // 构造空的string类对象s1
string s2("hello hmylq"); // 用C格式字符串构造string类对象s2,即包含'\0'
string s3(s2); // 拷贝构造s3
}
来分别看一下它们的值
这样就成功初始化了.
与从同时初始化的方法还有一种,就是赋值运算符重载"=",也可以进行初始化.
string s = "lqhmy";
2. string类对象的容量操作size(重点) 返回字符串有效字符长度
length 返回字符串有效字符长度
capacity 返回空间总大小
empty (重点) 检测字符串释放为空串,是返回true,否则返回false
clear (重点) 清空有效字符
reserve (重点) 为字符串预留空间
resize (重点) 将有效字符的个数该成n个,多出的空间用字符c填充
void Teststring()
{
// 注意:string类对象支持直接用cin和cout进行输入和输出
string s("hello, hmylq!");
cout<< s.size()<< endl;
cout<< s.length()<< endl;
cout<< s.capacity()<< endl;
cout<< s<< endl;
}
capacity为当前底层空间容量,而size和length为当前字符串大小.
可以看到已经将字符串s的大小输出出来了.
void Teststring()
{
string s("hello, hmylq!");
// 将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小
s.clear();
cout<< s.size()<< endl;
cout<< s.capacity()<< endl;
}
此时clear是将字符串清空,大小变为0,但是容量不会改变.
void Teststring()
{
string s("hello, hmylq!");
// 将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小
s.clear();
// 将s中有效字符个数增加到10个,多出位置用'a'进行填充
// “aaaaaaaaaa”
s.resize(10, 'a');
cout<< s.size()<< endl;
cout<< s.size()<< endl;
cout<< s.capacity()<< endl;
}
注意是将有效字符增加到10个,并不是容量!
可以看到resize已经成功把10个字符用’a'进行了填充.
resize还有注意的是,如果第二个参数不给值,会默认缺省值为'\0'
看下面的例子
void Teststring()
{
string s("hello, hmylq!");
// 将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小
s.clear();
// 将s中有效字符个数增加到10个,多出位置用'a'进行填充
// “aaaaaaaaaa”
s.resize(10, 'a');
// 将s中有效字符个数增加到15个,多出位置用缺省值'\0'进行填充
// "aaaaaaaaaa\0\0\0\0\0"
// 注意此时s中有效字符个数已经增加到15个
s.resize(15);
cout<< s.size()<< endl;
cout<< s.capacity()<< endl;
cout<< s<< endl;
}
此时虽然字符串显示的是10个‘a',但是有效字符长度已经到了15,再向后插入字符将会在第16个字符进行插入.
void Teststring()
{
string s("hello, hmylq!");
// 将s中的字符串清空,注意清空时只是将size清0,不改变底层空间的大小
s.clear();
s.resize(10, 'a');
// 将s中有效字符个数缩小到5个
s.resize(5);
cout<< s.size()<< endl;
cout<< s.capacity()<< endl;
cout<< s<< endl;
}
可以看到有效长度已经缩小到了5个,但是总容量没有变化,而且这次是将有效字符长度缩小,所以会将多余的字符舍弃掉,只会留下前5个字符.
reserve
void Teststring()
{
string s;
// 测试reserve是否会改变string中有效元素个数
s.reserve(100);
cout<< s.size()<< endl;
cout<< s.capacity()<< endl;
}
来看结果
可以看到reserve并没有改变size即有效元素的个数,只改变了容量大小,但我们开辟了100个空间,但为什么容量是111呢?
其实系统开辟空间默认是15个字节,当不满足需求时,将每次以1.5倍的速度扩容,直到大于或者等于指定的容量.
void Teststring()
{
string s;
s.reserve(100);
// 测试reserve参数小于string的底层空间大小时,是否会将空间缩小
s.reserve(50);
cout<< s.size()<< endl;
cout<< s.capacity()<< endl;
}
结果如下:
可以看到空间并不会缩小,依然是111.
与此同时有需要注意的几个点如下:
3. string类对象的访问及遍历操作1. size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
2. clear()只是将string中有效字符清空,不改变底层空间大小。
3. resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。
operator[] (重点) 返回pos位置的字符,const string类对象调用
begin+ end begin获取一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
rbegin + rend rbegin获取最后一个字符的迭代器 + rend获取第一个字符前一个位置的迭代器范围for C++11支持更简洁的范围for的新遍历方式
void Teststring()
{
string s1("hello lq");
const string s2("Hello hmy");
cout<< s1<< " "<< s2<< endl;
cout<< s1[0]<< " "<< s2[0]<< endl;
s1[0] = 'H';
cout<< s1<< endl;
// s2[0] = 'h'; 代码编译失败,因为const类型对象不能修改
}
可以看到我们直接用下标访问到string类中的第0个字符,当然还可以是别的下标位置.
获取到之后不仅可以使用,还可以进行修改.
例如我们将s1中的第一个字符'h'改成了'H'.
非常的方便.
下面说string的遍历.
一共有三种方法:
需要注意的以下三种方式除了遍历string对象,还可以遍历时修改string中的字符,
另外以下三种方式对于string而言,第一种使用最多
1.for+operator[]
for (size_t i = 0; i< s.size(); ++i)
cout<< s[i]<< endl
2.迭代器
string::iterator it = s.begin();
while(it != s.end())
{
cout<<*it<
3.范围for
for(auto& ch : s)
{
cout<< ch<< endl;
}
push_back 在字符串后尾插字符c
append 在字符串后追加一个字符串
operator+= (重点) 在字符串后追加字符串str
c_str(重点) 返回C格式字符串
find + npos(重点) 从字符串pos位置开始往后找字符c,返回该字符在字符串中的位置
rfind 从字符串pos位置开始往前找字符c,返回该字符在字符串中的位置
substr 在str中从pos位置开始,截取n个字符,然后将其返回
接下来看各接口的使用
void Teststring()
{
string str;
str.push_back(' '); // 在str后插入空格
str.append("hello"); // 在str后追加一个字符"hello"
str += 'h'; // 在str后追加一个字符'h'
str += "lq"; // 在str后追加一个字符串"lq"
cout<< str<< endl;
cout<< str.c_str()<< endl; // 以C语言的方式打印字符串
}
看输出结果
可以发现都已经成功插入了
在string中push_back只能插入字符,append只能追加字符串,当然字符串可以是一个字母.
而+=既可以插入字符也可以插入字符串,所以我们平常使用+=居多.
void Teststring()
{
// 获取file的后缀
string file("string.cpp");
size_t pos = file.rfind('.');
string suffix(file.substr(pos, file.size() - pos));
cout<< suffix<< endl;
}
我们都知道文件后缀是以 . 结尾
我们想获取文件的后缀名,首先要先找到.的位置,利用find或者rfind(这里使用rfind因为.一般都是偏后,所以是从后向前找),然后如果找到了,会返回这个位置的下标,否则返回npos,然后我们想获取.后面的内容,可以利用substr切取子串,从第6个位置开始,向后截取(总大小-6)个长度,即.后面的长度,这样就可以获得了.
其中的npos 是string中的一个静态成员变量
static const size_t npos = -1;
void Teststring()
{
// 取出url中的域名
string url("http://www.cplusplus.com/reference/string/string/find/");
cout<< url<< endl;
size_t start = url.find("://");
//如果start等于了npos,说明没有找到,即这个url是非法的.
if (start == string::npos)
{
cout<< "invalid url"<< endl;
return;
}
//如果找到了,因为此时位置是在':'这个位置,所以必须将这个位置+=3跳过这个位置,此时的位置在"://www"中的第一个w位置
start += 3;
//然后开始寻找第一个/位置
size_t finish = url.find('/', start);
//此时从start到finsh之间的东西就是我们所需要的url域名
string address = url.substr(start, finish - start);
cout<< address<< endl;
}
上面的就是取出url域名的操作了
在这个操作中需要注意的是:
5.string类非成员函数1. 在string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
2. 对string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
operator+ 尽量少用,因为传值返回,导致深拷贝效率低
operator>> (重点) 输入运算符重载
operator<< (重点) 输出运算符重载
relational operators(>,>=,<,<=,==) (重点) 大小比较
这里前三个前面已经说过了,主要说一下最后一个,就是字符串可以利用大于、小于、等于号等进行比较(按字典序比较)
void Teststring()
{
string s1("abcde");
string s2("bcdef");
if (s1 >s2)
cout<< "s1 >s2"<< endl;
else if (s1< s2)
cout<< "s1< s2"<< endl;
else
cout<< "s1 == s2"<< endl;
}
结果应当是s1 符合了我们预期的结果. 这里想说明字符串可以直接利用运算符进行比较大小. stl的string的使用就到此结束了,下一章将详细讲述它的模拟实现. 如果有疑问或者错误的地方,欢迎提出或指正哦. 你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
分享题目:C++STL之string的使用-创新互联
本文URL:http://cdweb.net/article/ppjje.html