资讯 小学 初中 高中 语言 会计职称 学历提升 法考 计算机考试 医护考试 建工考试 教育百科
栏目分类:
子分类:
返回
空麓网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
空麓网 > 计算机考试 > 软件开发 > 后端开发 > Java

STL ——String

Java 更新时间: 发布时间: 计算机考试归档 最新发布

STL ——String

目录

一、STL介绍

A.什么是STL

B.STL六个组件

C.STL的缺陷

二、String

A.String介绍

B.String常用接口

1.构造

2.析构

3. String类对象的容量操作

4.String类对象的访问操作 

5.string类对象的修改操作

6.非成员函数重载


一、STL介绍

A.什么是STL

STLL(standard template libaray-标准模板库)是C++标准库的重要组成部分,不仅是一个可复用的组件库,而且是一个包罗数据结构与算法的软件框架。

B.STL六个组件

C.STL的缺陷

1. STL库的更新太慢了。 2. STL现在都没有支持线程安全。并发环境下需要我们自己加锁。且锁的粒度是比较大的。 3. STL极度的追求效率,导致内部比较复杂。比如类型萃取,迭代器萃取。 4. STL的使用会有代码膨胀的问题,比如使用vector/vector/vector这样会生成多份代码,当然这是模板语法本身导致的。

二、String

A.String介绍

1.字符串是表示字符序列的类 2.该类的接口与常规容器的接口基本相同,再添加了一些专门用来操作string的常规操作。 3. string在底层实际是:basic_string模板类的别名:  typedef basic_string string; 4. 不能操作多字节或者变长字符的序列 对于String类模板,其实也有其他的例如宽字符串、16/32位字符串,其作用是为了支持各国得字符实现。

B.String常用接口

1.构造

constructor
string()  (重点) 构造空的 string 类对象,即空字符串
string(const char* s) (重点) 用 C-string(字符串) 来构造 string 类对象
string(size_t n, char c) string 类对象中包含 n 个字符 c
string(const string&s) (重点) 拷贝构造函数
string (const string& str, size_t pos, size_t len = npos);
用子字符串构造string对象
string (const char* s, size_t n);
根据字符串的一个序列来构造string对象
string (size_t n, char c);
用连续的字符c填充string对象
template string (InputIterator first, InputIterator last);
相同的顺序复制范围[first,last)中的字符序列。
string (string&& str) noexcept;

获取str的内容。

str处于未指定但有效的状态。

简单来说就是想要获取一些数据必须要带上这个括号,例如s.size()、s.capacity()等等

2.析构

~string(); 默认析构函数,调用自定义类型的析构函数对内置类型不处理需要我们显示实现。

3. String类对象的容量操作

capacity
size (重点) 返回字符串有效字符长度
length 返回字符串有效字符长度
capacity 返回空间总大小
empty (重点) 检测字符串释放为空串,是返回 true ,否则返回 false
clear (重点) 清空有效字符
reserve (重点) 为字符串预留空间 * *
resize (重点) 将有效字符的个数该成n个,多出的空间用字符c填充

1.  size是计算字符串长度,在string类中他的值和用法和length相同 ,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。 

需要注意的是 空格 也算一个 size的。

2.  capacity是返回string所占空间的大小,此容量不一定等于字符串长度。它可以相等或更大,额外的空间允许对象在向字符串添加新字符时优化其操作。

capacity的理论最大值由max_size给出(没什么用)。

3.  empty:检测看string是不是空的(看length是否为0),不会对字符串做任何修改。

如果字符串是空的则会返回 true  ,不是空的则返回 false。

bool empty() const noexcept;

4.  clear:清空有效字符,直到length为0。(erase)

void clear() noexcept;

注意:capacity不会变。

5.  reserve:为string对象申请空间 以为了方便将size和length提升到n的操作。

void reserve (size_t n = 0);

注意:reserve只能申请空间,不能删除空间(在reserve中capacity只能增不能减) 

           reserve过后size不会变。

 6.  resize:把string对象改成一个size大小为n的对象。

void resize (size_t n); void resize (size_t n, char c);

如果n小于当前的size(length),则当前string将缩短,删除第 n 个字符以外的字符。

如果n大于当前的size(length),则会用我们resize的c字符来重复填充后面的字符串,如果没写c,则会默认填充空字符'0’

    // 将s中有效字符个数增加到10个,多出位置用'a'进行填充	// “aaaaaaaaaa”	s.resize(10, 'a');	cout << s.size() << endl;	cout << s.capacity() << endl;	// 将s中有效字符个数增加到15个,多出位置用缺省值'0'进行填充	// "aaaaaaaaaa00000"	// 注意此时s中有效字符个数已经增加到15个	s.resize(15);	cout << s.size() << endl;	cout << s.capacity() << endl;	cout << s << endl;	// 将s中有效字符个数缩小到5个	s.resize(5);	cout << s.size() << endl;	cout << s.capacity() << endl;	cout << s << endl;

通过上面这串代码我们可知 :

resize在改变size的同时,如果size增大,是会导致capacity增大的,反之,如果导致size减小,那capacity不会变。

4.String类对象的访问操作 

operator[ ]  ( 重 点) 返回 pos 位置的字符, const string 类对象调用
begin + end begin 获取一个字符的迭代器 + end 获取最后一个字符下一个位置的迭 代器
rbegin  和  rend begin 获取一个字符的迭代器 + end 获取最后一个字符下一个位置的迭 代器
范围 for C++11支持更简洁的范围for的新遍历方式

1.operator [ ]  

返回字符串中pos(下标,第一个是0)位置的引用(可读可写)

char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;

注意:1.如果pos等于size,那么会返回'0'的引用

           2.如果越界会报错。

另外 , at  也能达到相同的作用:

char& at (size_t pos); const char& at (size_t pos) const;(也是返回pos下标位置的引用),不同的是at会返回异常。需要捕捉。

2.begin和end

string::begin() 获取首字符的迭代器,例如str.begin() + 2,这里给的就是下标为2的字符的迭代器

string::end() 获取最后一个字符的下一个位置的迭代器

先记住迭代器的用法: string::iterator it = str.begin(); 定义一个迭代器,

#include #include int main (){  string str ("Test string");  for (string::iterator it=str.begin(); it!=str.end(); ++it)    {        cout << *it;    }  cout << 'n';  return 0;}

begin()和end()大多数使用在需要使用STL提供的算法操作string时,比如:采用reverse逆置string

其他时候基本用[ ]。

3.rbegin和rend 

和begin和end类似,不过rbegin和rend返回的是反向迭代器。

reverse_iterator

rbegin()指向的最后一个字符串的反向迭代器(也就是反向迭代开头的位置的反向迭代器)

rend()是获取第一个字符之前的理论元素的反向迭代器(也就是反向最后一个字符的下一个位置的反向迭代器)

4.范围for

对于范围for,其实它的底层就是用迭代器进行迭代,auto所对应的类型其实就是迭代器类型。

for(auto e : str){  cout << e ;}cout << endl;//这里的e其实它的类型就是一个迭代器类型//auto e  ———— string :: iterator e;

5.operator=

string& operator= (const string& str); 
string& operator= (const char* s);
string& operator= (char c);

赋值重载操作符,capacity会变大但不会变小,size会随着赋值改变

6.对于string对象的增删查改等操作

 画表格太累了。。。直接从cplusplus.com上面截图了 ^ ^

1.operator += 

通过在当前字符串末尾增加字符串来扩大string,其返回值是被增加后的string的引用

加另一个str对象
string& operator+= (const string& str);
加一个字符串
string& operator+= (const char* s);
加一个字符
string& operator+= (char c);

2.append   追加

效果和operator += 相同,都是通过在当前字符串末尾增加字符串来扩大string,其返回值是被增加后的string的引用

增加一个str的拷贝
string& append (const string& str); 
增加str的一个子字符串的拷贝:从subpos位置开始依次sublen个(如果sublen过大就一直加到str的末尾位置)
string& append (const string& str, size_t subpos, size_t sublen);
增加s指向的字符串
string& append (const char* s);
增加s指向的字符串的前n个字符
string& append (const char* s, size_t n);
在原字符串后面填充n个字符c
string& append (size_t n, char c);
在原字符串后面增加另一个字符串的[first,last)范围的子字符串。(first和last是自己定的并不一定是从头开始到结束)
template    string& append (InputIterator first, InputIterator last);
以相同的顺序增加类对象il中每个字符的副本
string& append (initializer_list il);

 例:

#include #include int main (){  string str;  string str2="Writing ";  string str3="print 10 and then 5 more";  str.append(str2);                       // "Writing "  str.append(str3,6,3);                   // "10 "  str.append("dots are cool",5);          // "dots "  str.append("here: ");                   // "here: "  str.append(10u,'.');                    // ".........."  //这里就是通过改变迭代器的位置来控制了加的字符串范围  str.append(str3.begin()+8,str3.end());  // " and then 5 more"  str.append(5,0x2E);                // "....."  cout << str << 'n';  return 0;}

3.push_back 和pop_back

push_back :尾插一个字符,size和length +1 

void push_back (char c);

pop_back :尾删一个字符,size和length -1

void pop_back();

需要注意的是:push_back和pop_back只能尾插和尾删一个字符 而不能是字符串

4.assign

替换:用新的内容替换原字符串

用另一个str替换掉原来的字符串(注意如果str比原字符串短,那size会减小)
string& assign (const string& str);
用另一个字符串的子串(subpos位置之后的sublen个元素)替换掉原字符串
string& assign (const string& str, size_t subpos, size_t sublen);
用一个字符串替换掉原字符串
string& assign (const char* s);
用字符串s的从起始位置开始n个元素组成的子字符串替换掉原来的字符串
string& assign (const char* s, size_t n);
用n个c字符替换掉原来的字符串
string& assign (size_t n, char c);
以相同的顺序用范围[first,last)内字符序列替换原字符串
template    string& assign (InputIterator first, InputIterator last);
按照相同的顺序复制il中的每个字符。
string& assign (initializer_list il);
获取括号里面的内容
string& assign (string&& str) noexcept;
int main(){	string str;	string base = "The quick brown fox jumps over a lazy dog.";	str.assign(base);	cout << str << 'n';	str.assign(base, 10, 9);	cout << str << 'n';        // "brown fox"	str.assign("pangrams are cool", 7);	cout << str << 'n';        // "pangram"	str.assign("c-string");	cout << str << 'n';        // "c-string"	str.assign(10, '*');    cout << str << 'n';        // "**********"	str.assign(10, 0x2D);	cout << str << 'n';        // "----------"	str.assign(base.begin() + 16, base.end() - 12);	cout << str << 'n';        // "fox jumps over"	return 0;}

注意end()-1才是“.”哦。

5.insert

插入

在原字符串第pos位置后面插入str的拷贝
string& insert (size_t pos, const string& str);
在原字符串的第pos位置后面插入str的子串的拷贝,子串为str的subpos向后数sublen个字符所组成的字符串
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);
在原字符串第pos位置后面插入一个字符串的拷贝
string& insert (size_t pos, const char* s);
在原字符串的第pos位置后面插入一个字符串的前n个字符所组成的字符串的拷贝
string& insert (size_t pos, const char* s, size_t n);

在原字符串的第pos位置后面插入n个c字符的拷贝

注意:这里迭代器返回的是插入的c的迭代器的拷贝

string& insert (size_t pos,   size_t n, char c);iterator insert (const_iterator p, size_t n, char c);
插入字符c
iterator insert (const_iterator p, char c);
在迭代器p后面插入子序列的拷贝[first , end)
template iterator insert (iterator p, InputIterator first, InputIterator last);
按照相同的顺序插入il中每个字符的副本。
string& insert (const_iterator p, initializer_list il);
int main(){	string str = "to be question";	string str2 = "the ";	string str3 = "or not to be";	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	cout << *it << endl;                  // , 	str.insert(str.end(), 3, '.');        // to be, not to be: that is the question(...)	str.insert(it+2, str3.begin(), str3.begin() + 3);                                           // to be, (or )not to be: that is the question...	std::cout << str << 'n';	return 0;}

6.erase

删除string中的一部分,并使szie和length随之减小(capacity不变)

把字符串中从第pos下标位置以及向后len个字符删除掉

注意:

1.如果len给的过大超过了size,那么会删到末尾结束

2.默认的erase会吧string对象内部的元素全部删除,从开头删到结束

 string& erase (size_t pos = 0, size_t len = npos);
删除迭代器p所指向的元素
iterator erase (const_iterator p);

删除迭代器[first , last)的元素 

注意:first元素会被删除而last不会被删除

iterator erase (const_iterator first, const_iterator last);

注意:

1.pos是下标,是从0开始的

2.如果pos比size(length)大,那么会抛异常

3.最上面的返回*this ,另外两个返回的是迭代器(指向第一个被删除的位置目前所取代的字符的位置),如果全部被删光了就指向end() 

int main(){       string str2("The bao is a joker or a handsome boy");    cout << str2 << endl;    string::iterator it = str2.erase(str2.begin() + 13);//返回的是迭代器iterator it指向j原来所处的位置    cout << str2 << endl;    str2.erase(it, it + 10);    cout << str2 << endl;    return 0;}

7.replace

将字符串中从字符pos开始并跨越len个字符的部分(或[i1,i2)之间范围内的部分)替换为新内容:

将字符串中从pos开始后面len个元素替换为str,其余不变
string& replace(size_t pos, size_t len, const string& str);string& replace(const_iterator i1, const_iterator i2, const string&str);
将字符串中从pos开始后面len个元素替换为str对应的字符串中第subpos开始后面sublen个元素
string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);
将字符串中从pos开始后面len个元素替换为字符串s
string& replace (size_t pos,size_t len,const char* s);string& replace (const_iterator i1, const_iterator i2, const char* s);
将字符串中从pos开始后面len个元素替换为字符串s的前n个元素
string& replace (size_t pos, size_t len,const char* s, size_t n);string& replace (const_iterator i1, const_iterator i2, const char* s, size_t n);
用连续的n个字符c填充替换pos开始后面len个元素
string& replace (size_t pos,size_t len,size_t n, char c);string& replace (const_iterator i1, const_iterator i2, size_t n, char c);

以相同的顺序复制范围

[first,last)中的字符序列替换[i1,i2)中的内容。

template   string& replace (const_iterator i1, const_iterator i2,InputIterator first, InputIterator last);
按照相同的顺序复制il中的每个字符替换[i1,i2)中的内容
string& replace (const_iterator i1, const_iterator i2, initializer_list il);
int main(){	string base = "this is a test string.";	string str2 = "n example";	string str3 = "sample phrase";	string str4 = "useful.";	// Using positions:                 0123456789*123456789*12345	string str = base;                // "this is a test string."	str.replace(9, 5, str2);          // "this is an example string." (1)	str.replace(19, 6, str3, 7, 6);     // "this is an example phrase." (2)	str.replace(8, 10, "just a");     // "this is just a phrase."     (3)	str.replace(8, 6, "a shorty", 7);  // "this is a short phrase."    (4)	str.replace(22, 1, 3, '!');        // "this is a short phrase!!!"  (5)	// Using iterators:                                               0123456789*123456789*	str.replace(str.begin(), str.end() - 3, str3);                    // "sample phrase!!!"      (1)	str.replace(str.begin(), str.begin() + 6, "replace");             // "replace phrase!!!"     (3)	str.replace(str.begin() + 8, str.begin() + 14, "is coolness", 7);    // "replace is cool!!!"    (4)	str.replace(str.begin() + 12, str.end() - 4, 4, 'o');                // "replace is cooool!!!"  (5)	str.replace(str.begin() + 11, str.end(), str4.begin(), str4.end());// "replace is useful."    (6)	cout << str << 'n';	return 0;}

 8.swap

把原字符串和str交换

void swap (string& str);

9.pop_back 

 把最后一个字符给erase掉,length(size)-1.

5.string类对象的修改操作

c_str ( 重点 ) 返回C格式字符串
find + npos ( 重点) 从字符串 pos 位置开始往后找字符 c ,返回该字符在字符串中的位置
rfind 从字符串 pos 位置开始往前找字符 c ,返回该字符在字符串中的位置
substr 在 str 中从 pos 位置开始,截取 n 个字符,然后将其返回

1.c_str

返回指向一个字符串的指针,该字符串以'0'结尾

2.find

在字符串中搜索由其参数指定的序列的第一个匹配项。

当指定pos时,搜索仅包括原字符串位置pos处或之后的字符,忽略任何可能出现的位置pos之前的字符。

注意:与成员find_first_of不同,无论何时搜索多个字符,仅匹配其中一个字符是不够的,但必须匹配整个序列

查找和str序列的第一个匹配项的下标
size_t find (const string& str, size_t pos = 0) const;
查找和字符串s的第一个匹配项的下标
size_t find (const char* s, size_t pos = 0) const;
查找和字符串s的前n个元素组成的序的第一个匹配项的下标
size_t find (const char* s, size_t pos, size_t n) const;
查找字符s的第一个匹配项的下标位置
size_t find (char c, size_t pos = 0) const;

3.refind

从下标pos位置往前找,返回第一个匹配项(也就是字符串中从前往后数最后一个匹配项)的下标 

从pos下标位置开始往前找,返回第一个匹配项的下标
size_t rfind (const string& str, size_t pos = npos) const;
从pos下标位置开始往前找,返回第一个匹配项的下标
size_t rfind (const char* s, size_t pos = npos) const;
从pos下标位置开始往前找,返回第一个匹配项的下标(和s字符串的前n个字符组成的字符串匹配)
size_t rfind (const char* s, size_t pos, size_t n) const;
从pos下标位置开始往前找,返回第一个和字符c匹配的匹配项的下标
size_t rfind (char c, size_t pos = npos) const;

4.substr

string substr (size_t pos = 0, size_t len = npos) const;

返回一个新构造的对象,对原字符串从pos下标位置开始往后len个元素组成的字符串进行拷贝构造string对象。

注意:如果 pos 大于字符串长度,则会引发out_of_range异常。
 

int main (){  string str="We think in generalities, but we live in details.";                                           // (quoting Alfred N. Whitehead)  string str2 = str.substr (3,5);     // str2 "think"  size_t pos = str.find("live");      // position of "live" in str  string str3 = str.substr (pos);     // str3 "live in details"  cout << str2 << ' ' << str3 << 'n';  return 0;}

注意:

1.在string尾部追加字符时,push_back、append、+=三种的实现方式差不多,一般情况下用+=操作的比较多,因为+=不仅可以连接单个字符还可以连接字符串。

2.对stirng操作时,如果能够大概预估到放多少个字符,建议先用reserve吧空间开辟好。

6.非成员函数重载

operator+ 尽量少用,因为传值返回,导致深拷贝效率低
operator>> (重点) 输入运算符重载
operator<< (重点) 输出运算符重载
getline (重点) 获取一行字符串
relational operators (重点) 大小比较

1.operator+

返回一个新构造的字符串对象,其值为lhs中的字符与rhs中的字符串的串联。

(在lhs后面追加rhs)

在lhs后面追加rhs,返回追加之后的string对象的拷贝
string operator+ (const string& lhs, const string& rhs);
在string对象后面追加字符串和在字符串后面追加string对象,返回追加之后的拷贝
string operator+ (const string& lhs, const char*   rhs);string operator+ (const char*   lhs, const string& rhs);
在string对象后面追加字符和在字符后面追加string对象,返回追加之后的拷贝
string operator+ (const string& lhs, char rhs);string operator+ (char lhs, const string& rhs);

2.operator>>和operator<< 

 >>:从流中提取字符串

istream& operator>> (istream& is, string& str);

<<:将字符串插入流

ostream& operator<< (ostream& os, const string& str);

所返回的istream和ostream类型的引用都是为了连续流提取和连续流插入

int main(){	string name;	cout << "Please, enter your name: ";	cin >> name;	cout << "Hello, " << name << "!n";	return 0;}

3.getline

将一行数据从流中提取出来转换为string对象

从 is 中提取字符并将其存储到 str 中,直到找到分隔字符 delim
istream& getline (istream& is, string& str, char delim);
从 is 中提取字符并将其存储到 str 中,直到找到分隔字符——换行符“n”。
istream& getline (istream& is, string& str);

如果找到分隔符,则将其提取并丢弃(即不存储它,下一个输入操作将在它之后开始)。

请注意,调用之前的任何内容都将替换为新提取的序列。(即str会改变)

每个提取的字符都追加到字符串中,就像调用其成员push_back一样。

int main(){	string name;	cout << "Please, enter your full name: ";	getline(cin, name);	cout << "Hello, " << name << "!n";	return 0;}

4.relational operator(string)

判断string类对象之间、string类对象和字符串之间是否相等
bool operator== (const string& lhs, const string& rhs);bool operator== (const char*   lhs, const string& rhs);bool operator== (const string& lhs, const char*   rhs);

判断string类对象之间、string类对象和字符串之间是否不相等

bool operator!= (const string& lhs, const string& rhs);bool operator!= (const char*   lhs, const string& rhs);bool operator!= (const string& lhs, const char*   rhs);
判断string类对象之间、string类对象和字符串之间是否小于(从第一个字符开始向后比较,谁小谁就小)
bool operator<  (const string& lhs, const string& rhs);bool operator<  (const char*   lhs, const string& rhs);bool operator<  (const string& lhs, const char*   rhs);
判断string类对象之间、string类对象和字符串之间是否小于等于(从第一个字符开始向后比较,谁小谁就小)
bool operator<= (const string& lhs, const string& rhs);bool operator<= (const char*   lhs, const string& rhs);bool operator<= (const string& lhs, const char*   rhs);
和小于的重载类似
bool operator>  (const string& lhs, const string& rhs);bool operator>  (const char*   lhs, const string& rhs);bool operator>  (const string& lhs, const char*   rhs);
和小于等于的重载类似
bool operator>= (const string& lhs, const string& rhs);bool operator>= (const char*   lhs, const string& rhs);bool operator>= (const string& lhs, const char*   rhs);

 

转载请注明:文章转载自 http://www.konglu.com/
本文地址:http://www.konglu.com/it/1095573.html
免责声明:

我们致力于保护作者版权,注重分享,被刊用文章【STL ——String】因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理,本文部分文字与图片资源来自于网络,转载此文是出于传递更多信息之目的,若有来源标注错误或侵犯了您的合法权益,请立即通知我们,情况属实,我们会第一时间予以删除,并同时向您表示歉意,谢谢!

我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2023 成都空麓科技有限公司

ICP备案号:蜀ICP备2023000828号-2