C++ 之 string
C++ 的 string 类封装了很多对字符串的常用操作。
string 类是模板类 basic_string类,以 char作为其元素类型的类。
string 以单字节作为一个字符,如果处理多字符集编码的字符串,string仍以一个字节作为单个字符单位。
构造函数
(1) string() // 默认构造:构造一个空字符串
(2) string(const string &str) // 拷贝构造:复制另一个 string对象的内容
(3) string(const string & str, size_t pos, size_t len = npos) // 子串构造:以字符串 str的 pos位置开始,长度为 len的子串构造。
// 如果 len大于字符串长度或者 len为 npos(默认),则以字符串结束符为结尾构造。
(4) string(const char *s) // C风格字符串构造:以s开头,NULL结尾的C风格字符串构造
(5) string(const char *s, size_t n) // C风格字符子串构造:从s中拷贝n个字符构造
(6) string(size_t n, char c) // 字符填充构造:用 n个字符c构造字符串
(7) string(InputIterator first, InputIterator last) // 范围构造:用两个string迭代器之间的区域构造字符串
还有两种构造 initializer list 和 move constructor 不是很懂
赋值操作符 =
string& operator= (const string& str); // 用一个 string 为另一个string 赋值
string& operator= (const char *s); // 用C风格字符串为另一个string 赋值
string& operator= (char c); // 用一个字符为另一个string 赋值
还有另外两种 initializer_list 和 mov constructor 赋值不是很懂
迭代器
begin() // 返回指向字符串第一个字符的迭代器
end() // 返回指向字符串最后一个字符之后的迭代器,不能被解引用
rbegin() // 返回指向字符串最后一个字符的迭代器
rend() // 返回指向字符串第一个字符之前的迭代器,不能被解引用
cbegin(), cend(), crbegin(), crend() // 返回上述四种迭代器的 const 版本,不能通过解引用这些迭代器来修改 string,即便string 本身不是const 的
容积
size() 或 length() // 返回字符串包含的字符数,以字节作为字符分割,多字节编码的字符串可能不能得到正确字符数
// size_t size(); size_t length();
resize(size_t n) // 修改字符串的大小为n
// void resize(size_t n); void resize(size_t n, char c);
// 如果字符串的长度小于 n,则n个字符后面的字符被抛弃。
// 如果字符串长度大于n,则会延长字符串。如果制定了c,则会用字符c填充字符串,否则后面的字符将被值初始化(初始化为NULL)
capacity() // 返回已经为这个字符串分配的存储空间。capacity()的值一般比字符串长度大一些,以适应对字符串的增补操作。
// capacity() 的大小并不限制字符串的长度,当需要长度大于 capacity() 时,会重新分配空间,扩大 capacity()
// 可分配的最大长度用成员 max_size() 表示
// 使用成员函数 reserve 可以手动调整 capacity()的值
// size_t capacity();
max_size() // 返回字符串最大能分配的存储空间大小,不保证字符串一定能达到这个大小
// size_t max_size()
reserve(size_t n=0) // 修改为字符串分配的存储空间为 n,默认为0
// 主要用于为 capacity 括容,当 n > capacity 时,会为字符串增加分配空间,但如果 n > max_size ,会抛 std::length_error 异常
// 当 n < capacity() 时,相当于一个非绑定的 shrink操作,具体是否会减少存储空间,取决于实现。微软的编译器就不会减少空间,而g++编译器会
// 当 n < size() 时,相当于一个非绑定的 shrink_to_fit 操作,具体是否会减少存储空间,也取决于实现。
// 当 n < 0 时,会导致程序崩溃
// 当需要分配存储空间而失败时,会抛 std::bad_alloc异常
// void reserve(size_t n=0);
clear() // 清空当前字符串的所有字符,长度变为0
// void clear();
empty() // 测试当前字符串是否为空,若为空返回true, 否则返回false
// bool empty();
shrink_to_fit() // 将字符串的 capacity 减小到其 size的大小
// 这是一个non-binding的function,具体是否缩小取决于实现
// 如果需要分配存储空间,而分配失败,会抛 std::bad_alloc异常
元素访问
操作符[] // char& operator[] (size_t pos); const char& operator[](size_t pos) const;
// 返回字符串中位置在 pos的字符的引用。如果字符串是 const 的,则返回的字符也是 const;
// 如果 pos > size(); 会产生 undefined behavior
at() // char& at(size_t pos); const char& at(size_t pos) const;
// 功能同[],不过如果 n > size() 会抛 out_of_range 异常
front() // char& front(); const char& front() const;
// 返回字符串的第一个字符
// 不同于 begin() 返回第一个字符的迭代器,front() 直接返回这个字符的引用
// 对一个空字符串调用 front()会产生 undefined behavior
back() // char& back(); const char& back() const;
// 返回字符串的最后一个字符,如果对一个空字符串调用,会产生 undefined behavior
元素修改
操作符+= // 在字符串后面增添新的 string, C风格字符串,单个字符
// (1) string& operator += (const string& str); // 增添 string
// (2) string& operator += (const char * s); // 增添C风格字符串
// (3) string& operator += (const char c); // 增添单个字符
// (4) string& operator += (initializer_list<char> il); // 不懂
// 如果增添后的 length() > max_size() 会抛 length_error 异常
// 如果需要分配存储空间时失败,会跑 bad_alloc 异常
append() // 在字符串后面添加新的 string, string子串,C风格字符串,C风格字符子串,n个字符c,迭代器构成的子串
// (1) string& append(const string& str); // 增添 str
// (2) string& append(const string& str, size_t subpos, size_t sublen); // 增添str中,由 subpos开始,长度为 sublen的子串。 如果sublen到达字符串尾,或sublen > npos,则以字符串结束符为结束
// (3) string& append(const char *s); // 增添C风格字符串s
// (4) string& append(const char* s, size_t n); // 增添C风格字符串s的前 n个字符
// (5) string& append(size_t n, char c); // 连续增添 n 个字符c
// (6) string& append(InputIterator first, InputIterator last); // 添加迭代器之间的字符
// (7) string& append(initializer_list<char> il); // 不懂
// 如果 (3)中的 s 为NULL, 或(4)中的 n比s的长度长,都会产生 undefined behavior
// 如果 (2)中的 subpos 超过了 str的 length(),会抛 out_of_range异常
// 如果append结果的 length() 超过了 max_size(),会抛 length_error异常
// 如果在申请空间时失败,会抛 bad_alloc异常
push_back(char c) // 在string 后面添加一个字符 c
// void push_back(char c);
// 如果添加后,超过了 max_size(),则抛 length_error异常
// 如果在申请空间时失败,会抛 bad_alloc异常
pop_back() // 删除string 最后一个字符
// void pop_back();
assign() // 用一个新的字符串替代原有字符串
// (1) string& assign(const string& str) // 用string 替换 string
// (2) string& assign(const string& str, size_t subpos, size_t sublen); // 用str 的子串替换 string
// (3) string& assign(const char *s) // 用C风格字符串替换 string
// (4) string& assign(const char *s, size_t n) // 用C风格字符串的前 n个字符替换 string
// (5) string& assign(size_t n, char c) // 用 n个字符c 替换string
// (6) string& assign(InputIterator first, InputIterator last); // 用迭代器间的内容替代 string
// (7) string& assign(initializer_list<char> il); // 不懂
// (8) string& assign(string&& str) noexcept; // 不懂
// 除了(8) 不抛异常以外,其他异常情况与 append() 相同
insert(size_t pos, ...) // 在制定位置之前插入字符串
// 支持 string, string子串,C风格字符串,C风格字符串前n个字符,n个字符c的插入方法
erase() // 清除字符串的一部分
// string& erase(size_t pos=0, size_t len=npos); // 清除从pos开始长度为len 的字符子串。
// 如果len > size() 则清除到字符串结尾。默认参数是清除整个字符串。
// 如果pos > length() 抛一个out_of_range异常,pos 可以等于 length() 这时,什么都不清除
// iterator erase(const_iterator p); 清除 p指向的字符,返回被删除字符那个位置的迭代器
// iterator erase(const_iterator first, const_iterator last); 清除迭代器[first, last)之间的内容, 返回原来first字符那个位置的迭代器
replace() // 将原字符串一段区域内的子串删除,并用一个新的字符串替换它
// 支持用 pos,len 的方式1 表示被删除的子串,如果pos > length() 会抛一个out_of_range异常。如果 pos == length() 则相当于在字符串后面添加。
// 如果 pos+len 超过了字符串尾,则将 pos后的字符串全部换成新的 string
// 支持用 const_iterator i1, const_iterator i2 的方式2 表示被删除的子串[i1, i2)
swap() // 交换两个string 的内容
// void swap(string &str);
// 另有非成员重载函数 void swap(string &str1, string &str2);
字符串操作
c_str() // 获得等效的 C风格字符串
// const char *c_str() const;
// 返回的指针是 string 用于存放字符串的实际指针。如果修改了返回值 char *c 的内容,string 同样也会被修改。(虽然返回值要求是 const char* 的,但是也可以通过强制类型转换修改它的值)
// 如果后续对string 进行了操作,那么前面得到的 char *s 可能会失效
data() // 与 c_str() 完全相同
get_allocator() // 不懂
copy() // size_t copy(char *s, size_t len, size_t pos=0) const;
// 在string中拷贝一个子串 到char *s 指向的字符串中。返回实际拷贝的字符数。
// 子串从 pos 开始,长度为len。如果pos > length(),抛一个 out_of_range 异常。如果 pos+len 超过string尾,则将pos 到字符串结束的所有字符拷贝。
// 如果 s 为空,或者不足够存放被拷贝的子串,则导致 undefined behavior
// copy() 方法不会自动添加字符串结束符 \0,如果copy导致覆盖了原有的\0,字符串会丢失结尾
find() // 查找目标字符串在源字符串中第一次出现的位置,返回这个位置。如果找不到,返回 string::npos
// size_t find(const char& str, size_t pos = 0) const; // 查找 string
// size_t find(cosnt char* s, size_t pos=0) const; // 查找 C风格字符串
// size_t find(const char *s, size_t pos, size_type n) const; // 查找 C风格字符串的前n 个字符
// size_t find(char c, size_t pos=0) const; // 查找单个字符 c
// 如果指定了 pos,那么就是对源字符串从 pos开始查找,pos之前的一律不管
// 如果 s不是一个字符串,或长度不够则产生 undefined behavior
rfind() // 查找目标字符串在源字符串中最后一个出现的位置
// 大体上和 find() 相同,不过 pos表示 作为查找起点的最后一个点
find_first_of // 查找指定字符串中的任意一个字符第一次出现的位置
// 重载情况与 find()基本相同,只不过支持不是匹配整个字符串,而是匹配制定字符串中的任意一个字符。
find_last_of // 查找指定字符串中的任意一个字符最后一次出现的位置
// find_first_of 的反向
find_first_not_of // 查找不属于制定字符串中任意一个字符的字符第一次出现的位置
// 重载情况与 find_first_of ,不过这次是匹配除制定字符串以外的任意字符
find_last_not_of // 查找不属于制定字符串中任意一个字符的字符最后一次出现的位置
// 重载情况与 find_first_of ,不过这次是匹配除制定字符串以外的任意字符
substr // 产生一个子串
// string substr(size_t pos=0, size_t len=npos) const;
// 将源字符串 pos 开始,长度为 len 的部分作为子串返回
// 如果 pos == length() 那么返回的是一个空串, 如果 pos > length() 抛 out_out_range 异常
// 如果 pos + len 超过字符串尾,那么把 pos 到字符串尾的所有字符作为子串返回
compare // 将字符串进行对比
// int compare(const string& str) const; //将两个 string 对比
// int compare(size_t pos, size_t len, const string& str) const; // 将一个子串与 string 对比
// int compare(size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) const; //对比两个子串
// int compare(const char *s) // 与C风格字符串对比
// int compare(size_t pos, size_t len, const char *s) // 与C风格字符串对比
// int compare(size_t pos, size_t len, const char *s, size_t n) // 子串与C风格字符串的前 n个字符对比
// 返回 0 :字符串相等
// < 0 : 要么是 string 对象第一个与对比字符串不同的字符比较小,或者是 string是对比字符串的一个前缀。
// > 0 : 要么是 string 对象第一个与对比字符串不同的字符比较大,或者是 对比字符串是string的一个前缀。
特殊常量
string::npos // 这是一个用于表示最大字符串长度的变量。实际字符串不可能达到这个长度
// 这是一个无符号整形变量,其值为 -1。但是一定不能将其做这种对比 npos < 0 ,由于 npos 是无符号整形,-1代表无符号整形的最大值,所以 npos < 0 为 false
非成员函数重载
+ 操作符 // 拼接两个字符串,组成一个新的 string 返回
// 支持 string+string string + char* string + char
关系运算符 // 对比两个字符串,支持 string 与 string , string 与 char* 的对比
// 包括 > >= < <= == !=
// 实际是调用了 compare()
swap // 交换两个 string ,前面已经提过
>> 操作符 // 从流中读入 str, str原来的值被覆盖,遇到分隔符会停止读入str
<< 操作符 // 从 str写入输出流
getline // 从流中读入字符写入 str中,如果制定了结束字符,则遇到结束字符停止。否则遇到换行符停止。
// istream& getline(istream& is, string& str, char delim); // 以 delim停止
// istream& getline(istream& is, string& str); // 以换行符停止
C++ 之 string的更多相关文章
- 透过WinDBG的视角看String
摘要 : 最近在博客园里面看到有人在讨论 C# String的一些特性. 大部分情况下是从CODING的角度来讨论String. 本人觉得非常好奇, 在运行时态, String是如何与这些特性联系上的 ...
- JavaScript String对象
本编主要介绍String 字符串对象. 目录 1. 介绍:阐述 String 对象的说明以及定义方式. 2. 实例属性:介绍 String 对象的实例属性: length. 3. 实例方法:介绍 St ...
- ElasticSearch 5学习(9)——映射和分析(string类型废弃)
在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...
- [C#] string 与 String,大 S 与小 S 之间没有什么不可言说的秘密
string 与 String,大 S 与小 S 之间没有什么不可言说的秘密 目录 小写 string 与大写 String 声明与初始化 string string 的不可变性 正则 string ...
- js报错: Uncaught RangeError: Invalid string length
在ajax请求后得到的json数据,遍历的时候chrome控制台报这个错误:Uncaught RangeError: Invalid string length,在stackoverflow查找答案时 ...
- c# 字符串连接使用“+”和string.format格式化两种方式
参考文章:http://www.liangshunet.com/ca/201303/218815742.htm 字符串之间的连接常用的两种是:“+”连接.string.format格式化连接.Stri ...
- 【手记】注意BinaryWriter写string的小坑——会在string前加上长度前缀length-prefixed
之前以为BinaryWriter写string会严格按构造时指定的编码(不指定则是无BOM的UTF8)写入string的二进制,如下面的代码: //将字符串"a"写入流,再拿到流的 ...
- JavaScript中String对象的方法介绍
1.字符方法 1.1 charAt() 方法,返回字符串中指定位置的字符. var question = "Do you like JavaScript?"; alert(ques ...
- 在多线程编程中lock(string){...}隐藏的机关
常见误用场景:在订单支付环节中,为了防止用户不小心多次点击支付按钮而导致的订单重复支付问题,我们用 lock(订单号) 来保证对该订单的操作同时只允许一个线程执行. 这样的想法很好,至少比 lock( ...
- BCL中String.Join的实现
在开发中,有时候会遇到需要把一个List对象中的某个字段用一个分隔符拼成一个字符串的情况.比如在SQL语句的in条件中,我们通常需要把List<int>这样的对象转换为“1,2,3”这样的 ...
随机推荐
- c语言和c++栈的简单实现以及构造器的原理
也就是训练将原来的c语言 用类表示出来.. 关于构造器: //1与类名相同 没有返回值 被系统生成对象时自动调用,用于初始化 //2 可以有参数 构造器重载 默认参数 //3 重载和默认不能同时存在, ...
- bzoj 1017: [JSOI2008]魔兽地图DotR【树形dp+背包】
bzoj上是一个森林啊--? dp还是太弱了 设f[i][j][k]为到点i,合成j个i并且花费k金币能获得的最大力量值,a[i]为数量上限,b[i]为价格,p[i]为装备力量值 其实这个状态设计出来 ...
- bzoj 3894 文理分科【最小割+dinic】
谁说这道和2127是双倍经验的来着完全不一样啊? 数组开小会TLE!数组开小会TLE!数组开小会TLE! 首先sum统计所有收益 对于当前点\( (i,j) \)考虑,设\( x=(i-1)*m+j ...
- bzoj 1607: [Usaco2008 Dec]Patting Heads 轻拍牛头【瞎搞】
某种意义上真毒瘤?我没看懂题啊...于是看了题解 就是筛约数的那种方法,复杂度调和级数保证O(nlogn) 所以这题啥意思啊 #include<iostream> #include< ...
- springboot(六)自动配置原理和@Conditional
官方参考的配置属性:https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#common-appl ...
- Quartz.NET一个开源的作业调度框架
Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET允许开发人员根据时间间隔(或天)来调度作业.它实现了作业和 ...
- #undef及其用法
简 介 在后面取消以前定义的宏定义 在此程序中,我们将取消在先前程序中对预处理器的定义. #include <stdio.h> int main( void ) { #define ...
- elasticsearch全文搜索
1.创建索引 PUT 192.168.100.102:9200/news 2.创建mapping POST 192.168.100.102:9200/news/new/_mapping { " ...
- 《windows核心编程系列》四谈谈进程的建立和终止
第二部分:工作机理 第一章:进程 上一章介绍了内核对象,这一节开始就要不断接触各种内核对象了.首先要给大家介绍的是进程内核对象.进程大家都不陌生,它是资源和分配的基本单位,而进程内核对象就是与进程相关 ...
- 题解报告:hdu 2602 Bone Collector(01背包)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602 Problem Description Many years ago , in Teddy’s ...