赞
踩
大家在学习STL库的时候一定要学会看英文文档,俗话说熟能生巧,所以还得多练!在使用string类之前,要包含头文件#include <string>和using namespace std;
构造一个空字符串
string s1;
使用字符串构造一个实例化对象
string s2("hello world");
使用string的实例化对象去拷贝构造另外一个实例化对象
- string s2("hello world");
- string s3(s2);
- string s2("hello world");
- string s4 = s2;
string s5 = "hello world";
这里有一点需要注意,赋值运算符重载和拷贝构造的区别,两个对象都是定义之后的=是赋值运算符重载,如果是在定义的时候的=,属于拷贝构造;
所以代码1是不正确的:因为这是拷贝构造,而在拷贝构造这里,没有将一个字符拷贝给string类的函数实现
正确的写法:
- string s6;
- s6 = 'x';
拷贝str,在pos的下标开始,拷贝len个长度。
- string s7 = "hello world";
- string s8(s7, 0, 3);
从s上拷贝前n个字符
string s9("hello world", 4);
拷贝n个一样的字符
string s10(10, 'x');
用迭代器拷贝,first为头,last为尾,拷贝first<= string <last,也就是拷贝从first位置开始,在last前一个位置停下来,不拷贝last位置;(默认迭代器的end是在\0位置)
- string s11 = "hello world";
- string s12(s11.begin(), s11.end()-1);
可以从键盘上输入字符串,但是遇到空格就结束输入
- string s1;
- cin >> s1;
- cout << s1 << endl;
将字符串的内容打印到显示器上
从流中获取字符串,输入空格不会停止
- string s1;
- getline(cin, s1);
- cout << s1 << endl;
通过下标访问字符串元素
- string s1 = "hello world";
- cout << s1[0] << endl;
跟下标访问一样,只是报错的方式不同;
- string s1 = "hello world";
- cout << "字符串第5个字符为:" << s1.at(4) << endl;
begin获取字符串第一个字符的迭代器(可以理解取第一个字符的地址)
end获取最后一个字符的下一个位置的迭代器(可以理解取最后一个有效字符下一个位置的地址)
- string s1 = "hello world";
- string::iterator begin = s1.begin();
- string::iterator end = s1.end();
可以像指针那样的遍历
- string s1 = "hello world";
- string::iterator begin = s1.begin();
- string::iterator end = s1.end();
- while(begin < end)
- {
- cout << *begin << ' ';
- ++begin;
- }
- cout << endl;
也可以访问第几个位置的元素,但是一般用下标访问了
- string s1 = "hello world";
- string::iterator begin = s1.begin();
- string::iterator end = s1.end();
- cout << "访问第1个元素为:" << *begin << endl;
- cout << "访问第5个元素为:" << *(begin + 4) << endl;
- cout << "访问倒数第3个元素为:" << *(end - 3) << endl;
rbegin:指向的是最后一个有效字符的迭代器,从后往前访问;
rend:指向的是第一个字符之前的迭代器,从前往后访问;
- string s1 = "hello world";
- string::reverse_iterator rb = s1.rbegin();
- string::reverse_iterator re = s1.rend();
- while(rb < re)
- {
- cout << *rb << ' ';
- ++rb;
- }
很简洁,但是底层依旧是迭代器;
- string s1 = "hello world";
- for(auto e : s1)
- {
- cout << e << ' ';
- }
- cout << endl;
计算字符串的长度,以字节为单位
- string s1 = "hello world";
- int len = s1.size();
- cout << len << endl;
返回当前为字符串已经分配的空间大小,以字节为单位,这个空间表示出来的是给有效字符存的空间;
但是实际的空间大小是比capacity表示出来的多一个空间,是存\0的;
分配的空间会大于字符串的size,但是分配的空间有可能不同,这取决于不同的编译器;
- string s1 = "hello world";
- cout << s1.capacity() << endl;
判断字符串是否为空串:为空返回true(非0),不为空,返回false(0)
- string s1 = "hello world";
- cout << s1.empty() << endl;
- string s2;
- cout << s2.empty() << endl;
只清空字符串的有效内容,不销毁空间;清空内容之后,size为0,capacity不变
- string s3 = "hello world";
- cout << "清空之前的容量:" << s3.capacity() << endl;
- cout << "清空之前的长度:" <<s3.size() << endl;
-
- s3.clear();
- cout << "清空之后的容量:" << s3.capacity() << endl;
- cout << "清空之后的长度:" <<s3.size() << endl;
为字符串保留空间
规则:
1. 扩容:当保留的空间 > capacity,认为扩容。每个编译器扩容的空间是不同的,总体上看就是:实际扩容下的空间≥要保留的空间;
2. 缩容:当保留的空间 < capacity ,认为缩容。有的编译器不会缩容,有的编译器会缩容,如果保留的空间<size,只缩容到size大小。
- string s4 = "hello world";
- cout << "扩容之前的容量:" << s4.capacity() << endl;
- s4.reserve(100);
- cout << "扩容之后的容量:" << s4.capacity() << endl;
- string s4 = "hello world";
- cout << "缩容之前的容量:" << s4.capacity() << endl;
- s4.reserve(2);
- cout << "缩容之后的容量:" << s4.capacity() << endl;
- void resize (size_t n);
- void resize (size_t n, char c);
将有效字符的个数该成n个;
n > capacity :size = n ,capacity ≥ n,若提供c,则后面全为c字符,若没提供,则为‘\0’;并不是\0就是无效字符,对于有效字符的设定是根据在0~size-1之间的都是有效字符;
- string s5 = "hello world";
- cout << s5 << endl;
- cout << "调整有效字符之前的容量:" << s5.capacity() << endl;
- cout << "调整有效字符之前的长度:" <<s5.size() << endl;
-
- s5.resize(30);
- cout << s5 << endl;
- cout << "调整有效字符之后的容量:" << s5.capacity() << endl;
- cout << "调整有效字符之后的长度:" <<s5.size() << endl;
- string s5 = "hello world";
- cout << s5 << endl;
- cout << "调整有效字符之前的容量:" << s5.capacity() << endl;
- cout << "调整有效字符之前的长度:" <<s5.size() << endl;
-
- s5.resize(30, 'x');
- cout << s5 << endl;
- cout << "调整有效字符之后的容量:" << s5.capacity() << endl;
- cout << "调整有效字符之后的长度:" <<s5.size() << endl;
size < n < capacity ,size = n,capacity不变;若提供c,则后面全为c字符,若没提供,则为‘\0’;
n < size ,size = n ,删数据,保留前n个有效字符,capacity不变;
尾插字符
- string s1 = "hello world";
- cout << s1 << endl;
- s1 += 'x';
- cout << s1 << endl;
尾插字符串
- string s1 = "hello world";
- cout << s1 << endl;
- s1 += s1;
- cout << s1 << endl;
尾插字符串
- string s1 = "hello world";
- cout << s1 << endl;
- s1 += " hello CSDN";
- cout << s1 << endl;
在pos位置之前插入字符串
- string s1 = "hello world";
- string s2 = "CSDN";
-
- cout << "插入之前:" << s1 << endl;
- s1.insert(1, s2);
- cout << "插入之后:" << s1 << endl;
更多的应用:string::insert - C++ Reference
从pos位置删字符,删 len个字符;
npos代表-1,len为size_t类型,为无符号类型,就会被转换为整型的最大值,所以len为整型最大值,在不提供实参,就默认为npos;
- string s1 = "hello world";
- cout << "删除之前:" << s1 << endl;
- s1.erase(1,3);
- cout << "删除之后:" << s1 << endl;
删除迭代器所处的位置的字符
- string s1 = "hello world";
- cout << "删除之前:" << s1 << endl;
- s1.erase(s1.begin());
- cout << "删除之后:" << s1 << endl;
删除两个迭代器之间的字符,包括first,不包括last,[first, last)
- string s1 = "hello world";
- cout << "删除之前:" << s1 << endl;
- s1.erase(s1.begin(), s1.end()-1);
- cout << "删除之后:" << s1 << endl;
在pos位置向后查找str这个string类的对象,返回找到的字符串的第一个位置的下标,没找到就返回npos | size_t find (const string& str, size_t pos = 0) const; |
---|---|
在pos位置向后查找s这个字符串,返回找到的字符串的第一个位置的下标,没找到就返回npos | size_t find (const char* s, size_t pos = 0) const; |
在pos位置向后找,找s的前n个字符,找到返回第一个位置的下标,找不到返回npos | size_t find (const char* s, size_t pos, size_t n) const; |
在pos位置向后查找字符c,返回找到的字符位置的下标,没找到就返回npos | size_t find (char c, size_t pos = 0) const; |
具体查看:hstring::find - C++ Reference
rfind就是从后往前找
意思就是构造一个子串,从pos位置开始,往后len个字符都构造;
- string s2 = "hello world";
- size_t n = s2.find('w', 0);
- string s3 = s2.substr(n,s2.size() - n);
- cout << s2 << endl;
- cout << s3 << endl;
大家试着去官网去查查,一定要熟悉英文文献哦~
relational operators (string) - C++ Reference
UTF-8 | string |
UTF-16 | u16string |
UTF-32 | u32string |
宽字符(双字节字符) | wstring |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。