C++ : STL容器之string剖析
止欲淬炼灵魂 2024-10-09 11:05:02 阅读 98
STL容器之string剖析
一、string 的迭代器(一)起始迭代器(二)末尾迭代器(三)反向迭代器
二、容量相关的函数(一)size(二)capacity(三)resize(四)reserve(五)clear(六)empty
三、元素的访问和修改(一)[ ]操作符重载和 at(二)front 和 back
三、元素的修改(一)+= 运算符重载(二)append(三)push_back(四)assign(五)insert(六)erase(七)pop_back
四、其它操作函数(一)c_str(二)substr(三)find
五、其他成员(一)静态成员 npos(二)全局函数 getline结束语
一、string 的迭代器
迭代器的原理:下面的实现中迭代器是由 typedef / using 关键字定义的类型
<code>public:
/*using iterator = char*;
using const_iterator = const char*;*/
typedef char* iterator;
typedef const char* const_iterator;
(一)起始迭代器
返回第一个元素的迭代器
<code>iterator begin()
{ -- -->
return _str;
}
const_iterator begin() const
{
return _str;
}
(二)末尾迭代器
返回最后一个元素的下一个位置的迭代器
<code>iterator end()
{ -- -->
return _str + _size;
}
const_iterator end() const
{
return _str + _size;
}
(三)反向迭代器
和前面两个迭代器的实现原理相同,但是在遍历的时候要记得用++,而不是- -。
<code>
void test05() { -- -->
string s1("hello, world");
std::string::reverse_iterator it = s1.rbegin();
while (it != s1.rend()) {
cout << *it;
it++; //这里要用++
}
}
二、容量相关的函数
(一)size
返回函数的元素数量,不包含’\0’.
<code>size_t size() const
{ -- -->
return _size;
}
(二)capacity
返回 string 申请空间的大小
(三)resize
修改函数的元素大小。
使用规则:
如果 n 小于当前字符串长度,则当前值将缩短为其前 n 个字符,并删除第 n个字符以外的字符。
如果 n 大于当前字符串长度,则通过在末尾插入所需数量的字符来扩展当前内容,以达到 n 的大小。如果指定了 c,则新元素将初始化为 c 的副本,否则,它们是值初始化字符(空字符)。
(四)reserve
请求根据计划的大小更改调整字符串容量,使得容量至少为 n 个字符。
如果 n 大于当前字符串容量,则该容器将其容量增加到 n 个字符(或更大)除此之外,不做其他的改变。
此函数对字符串长度没有影响,也无法更改其内容。
(五)clear
清空字符串,使得元素数量改成0, 其它不改变。
<code>void clear()
{ -- -->
_str[0] = '\0';
_size = 0;
}
(六)empty
判断容器是否为空。
三、元素的访问和修改
(一)[ ]操作符重载和 at
重载[ ]操作符可以使得我们可以像数组一样的访问容器中的元素。重载有两个版本,const 对象使用const 版本,只读不可修改,普通版本可以读取和修改。
at 和[ ]几乎一致,只是写法上有略微差距。
<code>char& operator[](size_t i)
{ -- -->
assert(i >= 0 && i < _size);
return _str[i];
}
const char& operator[](size_t i) const
{
assert(i >= 0 && i < _size);
return _str[i];
}
(二)front 和 back
分别返回起始元素和末尾元素,和[ ] 一样,分别都有两个版本。
三、元素的修改
(一)+= 运算符重载
+= 是很好用的一个追加字符 / 字符串的运算符。
(二)append
在字符串末尾追加字符 / 字符串,版本有很多。
(三)push_back
在末尾追加字符,其实和前面两者区别不大,为了达到容器的一致性而添加的字符。
(四)assign
相当于构造函数,构造方式更多样化,下面的接口都有很多一致性。和追加的这套体系很像。
<code>#include <iostream>
#include <string>
int main ()
{ -- -->
std::string str;
std::string base="The quick brown fox jumps over a lazy dog.";code>
// used in the same order as described above:
str.assign(base);
std::cout << str << '\n';
str.assign(base,10,9);
std::cout << str << '\n'; // "brown fox"
str.assign("pangrams are cool",7);
std::cout << str << '\n'; // "pangram"
str.assign("c-string");
std::cout << str << '\n'; // "c-string"
str.assign(10,'*');
std::cout << str << '\n'; // "**********"
str.assign<int>(10,0x2D);
std::cout << str << '\n'; // "----------"
str.assign(base.begin()+16,base.end()-12);
std::cout << str << '\n'; // "fox jumps over"
return 0;
}
(五)insert
insert 函数的用法和之前都有一致性,只是多加了两个迭代器版本和插入元素的位置,因为涉及到数据的挪动,因此时间复杂度比较高,在项目中不建议使用。
<code>#include <iostream>
#include <string>
int main ()
{ -- -->
std::string str="to be question";code>
std::string str2="the ";code>
std::string str3="or not to be";code>
std::string::iterator it;
// used in the same order as described above:
str.insert(6,str2); // to be (the )question
str.insert(6,str3,3,4); // to be (not )the question
str.insert(10,"that is cool",8); // to be not (that is )the question
str.insert(10,"to be "); // to be not (to be )that is the question
str.insert(15,1,':'); // to be not to be(:) that is the question
it = str.insert(str.begin()+5,','); // to be(,) not to be: that is the question
str.insert (str.end(),3,'.'); // to be, not to be: that is the question(...)
str.insert (it+2,str3.begin(),str3.begin()+3); // (or )
std::cout << str << '\n';
return 0;
}
(六)erase
和 insert类似,由于牵涉到数据的挪动,因此并不推荐使用。
(七)pop_back
用来弹出最后一个字符
四、其它操作函数
(一)c_str
这个函数用来得到 string 里面的字符串,由于返回的是const 类型,因此要使用的话需要拷贝一份。
实现原理
<code>const char* c_str() const
{ -- -->
return _str;
}
使用样例
#include <iostream>
#include <cstring>
#include <string>
int main ()
{
std::string str ("Please split this sentence into tokens");
char * cstr = new char [str.length()+1];
std::strcpy (cstr, str.c_str());
// cstr now contains a c-string copy of str
char * p = std::strtok (cstr," ");
while (p!=0)
{
std::cout << p << '\n';
p = std::strtok(NULL," ");
}
delete[] cstr;
return 0;
}
(二)substr
用来获取 string 容器的字串,返回一份拷贝。
实现原理
<code>string string::substr(size_t pos, size_t len)
{ -- -->
assert(pos >= 0 && pos < _size);
if (len > _size - pos) {
len = _size - pos;
}
WGM::string s;
s.reserve(len);
for (int i = 0; i < len;i++)
{
s._str[i] = _str[pos++];
}
return s;
}
(三)find
查找指定的字符 / 字符串 / string串,默认从0位置开始查找。
一般和npos
混合起来使用,来判断是否找到目标字符串。
使用样例
<code>#include <iostream> // std::cout
#include <string> // std::string
int main()
{ -- -->
std::string str("There are two needles in this haystack with needles.");
std::string str2("needle");
// different member versions of find in the same order as above:
std::size_t found = str.find(str2);
if (found != std::string::npos)
std::cout << "first 'needle' found at: " << found << '\n';
found = str.find("needles are small grkwgeio", found + 1, 1);
if (found != std::string::npos)
std::cout << "second 'needle' found at: " << found << '\n';
found = str.find("haystack");
if (found != std::string::npos)
std::cout << "'haystack' also found at: " << found << '\n';
found = str.find('.');
if (found != std::string::npos)
std::cout << "Period found at: " << found << '\n';
// let's replace the first needle:
str.replace(str.find(str2), str2.length(), "preposition");
std::cout << str << '\n';
return 0;
}
五、其他成员
(一)静态成员 npos
用来表示整形的最大值
(二)全局函数 getline
从流中提取字符串到 str 中,直到遇到限定标识符 delim结束, 不写的化自动是<code>\n.
结束语
许久未更,从头开始!接下来还会带来 Linux 的文章,小编会继续更新有用的内容!
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。