C++ string类型小结
- 构造函数
- string.append()
- string.assign()
- string.at()
- string.back()
- string.begin()
- string.capasity()
- string.cbegin()
- string.clear()
- string.compare()
- string.copy()
- string.crbegin()
- string.c_str()
- string.data()
- string.empty()
- string.erase()
- string.find()
- string.find_first_not_of(str)
- string.find_first_of(str)
- string.find_last_not_of(str)
- string.find_last_of(str)
- string.front()
- string.get_allocator()
- string.insert()
- string.length()
- string.max_size()
- string.operator+=
- string.operator=
- string.operator[]
- string.pop_back()
- string.push_back()
- string.rbegin()
- string.replace()
- string.reserve()
- string.resize()
- string.rfind()
- string.shrink_to_fit()
- string.size()
- string.substr()
- string.swap()
- [string.npos]
- getline(string)
- relational operators(string)
参考 权威网站
左边的目录列举了关于string的 一些 成员。
构造函数
默认 string();
从已有复制 string (const string& str);
从已有剪辑 string (const string& str, size_t pos, size_t len = npos);
从字符数组录入 string (const char* s);
从字符数组录入n位
string (const char* s, size_t n);
用字符填充
string (size_t n, char c);
从迭代器填充
template <class InputIterator>
string (InputIterator first, InputIterator last);
析构函数:就普通析构函数没什么好讲的你又用不到
string.append()
在已有字符串后面添加字符串
正常的添加 string& append (const string& str);
截取后添加 string& append (const string& str, size_t subpos, size_t sublen);
用字符数组添加 string& append (const char* s);
截取字符数组添加 string& append (const char* s, size_t n);
string& append (const char* s, size_t subpos, size_t sublen)
添加单一字符 string& append (size_t n, char c);
用迭代器添加
template <class InputIterator>
string& append (InputIterator first, InputIterator last);
而且这个函数不仅调用可以改变字符串,也可以直接返回改变后的字符串
cout << a.append("lover!");
这样既改变了a同时也可以直接输出改变后的a
string.assign()
重新构造字符串,跟构造函数是一样的但是你用不了构造函数只能来用这个
默认 string& assign (const string& str);
截取 string& assign (const string& str, size_t subpos, size_t sublen);
字符数组 string& assign (const char* s);
截取字符数组 string& assign (const char* s, size_t n);
string& assign(const char* s, size_t subpos, size_t sublen);
单一字符填充
string& assign (size_t n, char c);
迭代器填充
template <class InputIterator>
string& assign (InputIterator first, InputIterator last);
string.at()
返回字符串某个位置的字符
char& at (size_t pos);
const char& at (size_t pos) const;
(好像上下两个没什么区别嘛……)
注意这里是从0开始的。
如果你给的数字大于该字符串的长度,就会抛出out_of_range类型异常
string.back()
c++11 only
返回的是字符串最后一个字符的引用
char& back();
const char& back() const;
但是正常编译的版本好像没有这个功能……需要加上-std=c++11编译选项。
string.begin()
string.end()
返回第一个字符的迭代器
iterator begin();
const_iterator begin() const;
权威网站举了个例子
int main ()
{
std::string str ("Test string");
for ( std::string::iterator it=str.begin(); it!=str.end(); ++it)
std::cout << *it;
std::cout << '\n';
return 0;
}
迭代器是可以自增的,曾经也有某位大佬写过迭代器,在篇文章中用浏览器的搜索功能搜索“迭代器”就可以找到
string.capasity()
返回的是string所占的内存空间。用字节表示
size_t capacity() const;
他没什么用因为他的返回值只是不小于字符串长度
// comparing size, length, capacity and max_size
int main ()
{
std::string str ("Test string");
std::cout << "size: " << str.size() << "\n";
std::cout << "length: " << str.length() << "\n";
std::cout << "capacity: " << str.capacity() << "\n";
std::cout << "max_size: " << str.max_size() << "\n";
return 0;
}
可能会输出
size: 11
length: 11
capacity: 15
max_size: 429496729
string.cbegin()
c++11 only
// string::cbegin/cend
int main ()
{
std::string str ("Lorem ipsum");
for (auto it=str.cbegin(); it!=str.cend(); ++it)
std::cout << *it;
std::cout << '\n';
return 0;
}
(真是的用string.begin()和string.end()不好吗)
string.clear()
清空字符串
int main ()
{
char c;
std::string str;
std::cout << "Please type some lines of text. Enter a dot (.) to finish:\n";
do {
c = std::cin.get();
str += c;
if (c=='\n')
{
std::cout << str;
str.clear();
}
} while (c!='.');
return 0;
}
string.compare()
比较当前字符串和给定字符串
默认的全文比较 int compare (const string& str) const;
默认的截取比较 int compare (size_t pos, size_t len, const string& str) const;
这里的截取是a.compare(size_t pos, size_t len, const string& str) 截取a从pos后的第len位和整个str比较
都可以的截取比较 int compare (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen) const;
截取a从pos后的len位和str从subpos后的sublen为进行比较
然后就是把所有的string类型改成char* 类型
int compare (const char* s) const;
int compare (size_t pos, size_t len, const char* s) const;
然后由于你传入char* 所以是没有subpos的,只有sublen,也就是截取前n位和你比较
int compare (size_t pos, size_t len, const char* s, size_t n) const;
返回值:
str.compare(cmp_str);
0:两个字符串相等
<0:str比cmp_str小
>0:str比cmp_str大
这里的字符串的大小定义是:
小:从前往后第一个不相同的字符,str比cmp_str的字典序小,也就是找到最小的i,使得str[i]!=cmp_str[i],然后再比较字典序。或者str是cmp_str的前缀
大:除了小和等的情况外的所有情况(废话)
复杂度:线性
异常:如果指定长度大于字符串长度,会抛出out_of_range类型异常
string.copy()
复制字符串
size_t copy (char* s, size_t len, size_t pos = 0) const;
a.copy(s, len, pos)表示把a从pos后len位复制到s。注意s才是被覆盖的那个。
返回成功复制的长度。
会抛出out_of_range类型异常
string.crbegin()
string.crend()
c++11 only
const_reverse_iterator crbegin() const noexcept;
const_reverse_iterator crend() const noexcept;
返回的是关于string的迭代器const_reverse_iterator,就是反向迭代器。返回的crbegin()其实就是字符串结尾,crend()就是字符串开头
这个迭代器的运算规则也是反向的,也就是it=crbegin(); it++其实是反向增加,也就是逆序遍历
权威网站给了一个逆向输出的代码
int main ()
{
std::string str ("lorem ipsum");
for (auto rit=str.crbegin(); rit!=str.crend(); ++rit)
std::cout << *rit;
std::cout << '\n';
return 0;
}
(真是的用begin和end会死啊)
string.c_str()
把string类型的变量转变为char*类型
const char* c_str() const;
有很多c++的函数要求传入的参数都是const char, 也就是字符数组。
string虽然被称为字符串类型,但是和const char 却不是同一个类型。所以string里面就有这样一个成员函数,把string类型存储的字符串转换为字符数组类型。
string.data()
const char* data() const;
(这东西和c_str()有区别吗)
string.empty()
告诉你这个字符串是不是为空(也就是长度是否为0)
bool empty() const;
string.erase()
删除本字符串的一部分,剪短他的长度
sequence (1)
string& erase (size_t pos = 0, size_t len = npos);
character (2)
iterator erase (iterator p);
range (3)
iterator erase (iterator first, iterator last);
- sequence
这里传入了默认参数,如果什么都没有就会删掉整个字符串。
如果只有一个参数就是默认先填充第一个参数,也就是起始位置,从你给的位置一路删除到末尾。
如果有俩参数,就是正常的从pos一路删除len位
返回删除后的字符串的引用。 - character
传入一个迭代器,删除这个迭代器指向的字符
返回删除后迭代器指向的字符。
如果我们用字符数组来表示字符串的话,删除了char[5],那么删除之后因为字符串还要连续那么char[6]就会补上来,所以返回的字符就是原来的char[6] - range
用俩迭代器来表示一个范围,删除这个范围内的所有字符。
然后返回这个范围的下一个字符。
如果删除[begin,end)的话,那么返回的便是原来的char[end]
(自己去写代码验证一下啊?)
string.find()
string (1)
size_t find (const string& str, size_t pos = 0) const;
c-string (2)
size_t find (const char* s, size_t pos = 0) const;
buffer (3)
size_t find (const char* s, size_t pos, size_t n) const;
character (4)
size_t find (char c, size_t pos = 0) const;
- string
寻找str,从第pos位开始。
a.find(b,pos);这个pos是指a的pos,把a从pos开始找。
找到的是原字符串中的位置 - c_str
很正常的字符数组。 - buffer
截取s的前n位和a比较,pos和第一个函数的用法一样。 - character
找到一个字符。
时间复杂度:未定义,但应该在两个要匹配的长度相乘上线性。
string.find_first_not_of(str)
从当前字符里找到第一个不在str里面的字符。
string (1)
size_t find_first_not_of (const string& str, size_t pos = 0) const;
c-string (2)
size_t find_first_not_of (const char* s, size_t pos = 0) const;
buffer (3)
size_t find_first_not_of (const char* s, size_t pos, size_t n) const;
character (4)
size_t find_first_not_of (char c, size_t pos = 0) const;
在当前string里面找到第一个不在给定字符串str里面的字符并返回它的位置
pos表示忽略当前字符串的前pos-1位(从第pos位开始考虑,pos也包括进去了)
n就是取字符数组的前n位。
时间复杂度:未定义,应该是两个要匹配的字符串长度相乘
string.find_first_of(str)
...直译:在当前字符串中找到第一个在给定字符串str中的字符
string (1)
size_t find_first_of (const string& str, size_t pos = 0) const;
c-string (2)
size_t find_first_of (const char* s, size_t pos = 0) const;
buffer (3)
size_t find_first_of (const char* s, size_t pos, size_t n) const;
character (4)
size_t find_first_of (char c, size_t pos = 0) const;
用法和上面那个一样。
string.find_last_not_of(str)
string.find_last_of(str)
...直译...
string.front()
c++11 only
返回字符串第一个字符的引用
char& front();
const char& front() const;
string.get_allocator()
string.insert()
插入
string (1)
// 在pos位置插入str
string& insert (size_t pos, const string& str);
substring (2)
// 截取str的[subpos,subpos+sublen)插入到str的pos位置
string& insert (size_t pos, const string& str, size_t subpos, size_t sublen);
c-string (3)
// 在pos位置插入s
string& insert (size_t pos, const char* s);
buffer (4)
// 在pos位置插入s的前n位
string& insert (size_t pos, const char* s, size_t n);
fill (5)
// 在pos位置插入n个c
string& insert (size_t pos, size_t n, char c);
// 在p的迭代器后面插入n个c
void insert (iterator p, size_t n, char c);
single character (6)
// 在p迭代器后面插入字符c
iterator insert (iterator p, char c);
range (7)
// 在p迭代器后面插入[first, last)迭代器之间的字符
template <class InputIterator>
void insert (iterator p, InputIterator first, InputIterator last);
参考权威网站提供的代码
// inserting into a string
#include <iostream>
#include <string>
int main ()
{
std::string str="to be question";
std::string str2="the ";
std::string str3="or not to be";
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;
}
时间复杂度:未定义,但应该和新字符串的长度成线性。
string.length()
返回当前字符串的长度
size_t length() const;
string.max_size()
返回当前系统下字符串可以到达的最大长度。
size_t max_size() const;
string.operator+=
首先肯定要知道也有+这个重载运算符的
就是用来连接俩字符串
string (1)
string& operator+= (const string& str);
c-string (2)
string& operator+= (const char* s);
character (3)
string& operator+= (char c);
这个……看函数原型就知道了把……
给出经过个人修改的权威网站的样例代码:
// string::operator+=
#include <iostream>
#include <string>
int main ()
{
std::string name ("John");
std::string family ("Smith");
name + " K. "; // c-string
name += family; // string
name += '\n'; // character
std::cout << name;
return 0;
}
时间复杂度:未定义,但应该和新字符串的长度成线性。
string.operator=
很简单的一个赋值语句
string (1)
string& operator= (const string& str);
c-string (2)
string& operator= (const char* s);
character (3)
string& operator= (char c);
string.operator[]
从此之后你可以像访问字符数组那样用下标来访问字符串。
char& operator[] (size_t pos);
const char& operator[] (size_t pos) const;
string.pop_back()
c++11 only
删除字符串的最后一个字符
void pop_back()
string.push_back()
增加一个字符
void push_back(char c);
比如这样:
// string::push_back
#include <iostream>
#include <fstream>
#include <string>
int main ()
{
std::string str("b");
str.push_back('a');
std::cout << str << '\n';
return 0;
}
string.rbegin()
string.rend()
反过来遍历……这个和crbegin是一样的
// string::rbegin/rend
#include <iostream>
#include <string>
int main ()
{
std::string str ("now step live...");
for (std::string::reverse_iterator rit=str.rbegin(); rit!=str.rend(); ++rit)
std::cout << *rit;
return 0;
}
string.replace()
用给定字符串来代替原字符串里面的一些内容
// 用str来代替[pos,pos+len)之间的字符
// str的长度不受len的限制
string& replace (size_t pos, size_t len, const string& str);
// 用str来代替两个迭代器之间的字符
string& replace (iterator i1, iterator i2, const string& str);
substring (2)
// 用str[subpos,subpos+sublen)来代替[pos,pos+len)之间的字符。
string& replace (size_t pos, size_t len, const string& str,
size_t subpos, size_t sublen);
c-string (3)
// 用字符数组来代替
string& replace (size_t pos, size_t len, const char* s);
string& replace (iterator i1, iterator i2, const char* s);
buffer (4)
// 用字符数组的前n个来代替
string& replace (size_t pos, size_t len, const char* s, size_t n);
string& replace (iterator i1, iterator i2, const char* s, size_t n);
fill (5)
// 用n个字符c来代替
string& replace (size_t pos, size_t len, size_t n, char c);
string& replace (iterator i1, iterator i2, size_t n, char c);
range (6)
// 给定字符串str用迭代器来表示。
template <class InputIterator>
string& replace (iterator i1, iterator i2,
InputIterator first, InputIterator last);
贴上来自权威网站的代码
// replacing in a string
#include <iostream>
#include <string>
int main ()
{
std::string base="this is a test string.";
std::string str2="n example";
std::string str3="sample phrase";
std::string str4="useful.";
// replace signatures used in the same order as described above:
// Using positions: 0123456789*123456789*12345 // 这个是对齐给你看字符位置的
std::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)
std::cout << str << '\n';
return 0;
}
时间复杂度:未定义,应该在新字符串中成线性。
string.reserve()
不要跟我一样傻乎乎写成了reverse
用来扩容(?)的,给将来的字符串保留更多空间。
void reserve (size_t n = 0);
// string::reserve
#include <iostream>
#include <fstream>
#include <string>
int main ()
{
std::string str("0123");
using std::cout;
using std::endl;
cout<<str.capacity()<<endl;
str.reserve(100);
cout<<str.capacity()<<endl;
return 0;
}
string.resize()
重新调整大小
void resize (size_t n);
void resize (size_t n, char c);
如果n小于当前大小就直接砍掉
如果n大于当前大小就用默认(int)0或者给定字符c填充
string.rfind()
和find的功能一样,只不过从后向前找到第一个
string (1)
// 这里截断还是从截断[0,pos)之间的字符进行判断
size_t rfind (const string& str, size_t pos = npos) const;
c-string (2)
size_t rfind (const char* s, size_t pos = npos) const;
buffer (3)
size_t rfind (const char* s, size_t pos, size_t n) const;
character (4)
size_t rfind (char c, size_t pos = npos) const;
string.shrink_to_fit()
要求字符串通过判断当前储存的长度来智能缩小申请的容量
void shrink_to_fit();
可能说的不是很清楚,运行一下权威网站的代码就知道了。
// string::shrink_to_fit
#include <iostream>
#include <string>
int main ()
{
std::string str (100,'x');
std::cout << "1. capacity of str: " << str.capacity() << '\n';
str.resize(10);
std::cout << "2. capacity of str: " << str.capacity() << '\n';
str.shrink_to_fit();
std::cout << "3. capacity of str: " << str.capacity() << '\n';
return 0;
}
string.size()
你确定这和length不是一个东西?
size_t size() const;
string.substr()
string substr (size_t pos = 0, size_t len = npos) const;
截取并返回当前字符串的[pos,pos+len)
不会修改原字符串。
时间复杂度:未定义,一般和返回的字符串成线性。
string.swap()
和给定字符串交换值,两个字符串的值都会被修改。
void swap (string& str);
时间复杂度:常数
[string.npos]
就是最大长度
unsigned long long 下的-1
static const size_t npos = -1;
getline(string)
(1)
istream& getline (istream& is, string& str, char delim);
(2)
istream& getline (istream& is, string& str);
从输入流is读取一行(以'\n'位分界)字符串保存到str
relational operators(string)
就是一些自定义的重载运算符……大部分都是用来比较的,大小关系在compare函数里面有说明
(1)
bool operator== (const string& lhs, const string& rhs);
bool operator== (const char* lhs, const string& rhs);
bool operator== (const string& lhs, const char* rhs);
(2)
bool operator!= (const string& lhs, const string& rhs);
bool operator!= (const char* lhs, const string& rhs);
bool operator!= (const string& lhs, const char* rhs);
(3)
bool operator< (const string& lhs, const string& rhs);
bool operator< (const char* lhs, const string& rhs);
bool operator< (const string& lhs, const char* rhs);
(4)
bool operator<= (const string& lhs, const string& rhs);
bool operator<= (const char* lhs, const string& rhs);
bool operator<= (const string& lhs, const char* rhs);
(5)
bool operator> (const string& lhs, const string& rhs);
bool operator> (const char* lhs, const string& rhs);
bool operator> (const string& lhs, const char* rhs);
(6)
bool operator>= (const string& lhs, const string& rhs);
bool operator>= (const char* lhs, const string& rhs);
bool operator>= (const string& lhs, const char* rhs);
C++ string类型小结的更多相关文章
- 把《c++ primer》读薄(3-1 标准库string类型初探)
督促读书,总结精华,提炼笔记,抛砖引玉,有不合适的地方,欢迎留言指正. 问题1:养成一个好习惯,在头文件中只定义确实需要的东西 using namespace std; //建议需要什么再using声 ...
- Spring MVC控制层的返回类型--String类型与Bean类型
SpringMVC控制层的返回类型形式多样,现拿其中的两种--String类型与Bean类型作以说明. 一.测试项目的结构 说明:(jsp的名字没起好) 控制层:UserController.java ...
- ElasticSearch 5学习(9)——映射和分析(string类型废弃)
在ElasticSearch中,存入文档的内容类似于传统数据每个字段一样,都会有一个指定的属性,为了能够把日期字段处理成日期,把数字字段处理成数字,把字符串字段处理成字符串值,Elasticsearc ...
- 每日一记-mybatis碰到的疑惑:String类型可以传入多个参数吗
碰到一个觉得很疑惑的问题,Mybatis的parameterType为String类型的时候,能够接收多个参数的吗? 背景 初学Mybatis的时候,看的教程和书籍上都是在说基本的数据类型如:int. ...
- C#string类型总结
字符串的特性:不可变性,每对字符串做拼接或者重新赋值之类的操作,都会在内存中产生一个新的实例. 所以说,在.Net平台下,如果你对一个字符串进行大量的拼接赋值等操作,会产生大量的垃圾. --- ...
- java基础--java.util.Date类型小结
首先先来了解一下Date数据类型: . Date类型通常要和另一个 java.text.SimpleDateFormat类联合使用. 把long-->Date: public Date(long ...
- 【原创】Java和C#下String类型中的==和equals的原理与区别
一.Java下 1.几个例子 public static void main(String[] arge) { String str1 = new String("1234"); ...
- String类型的属性和方法
× 目录 [1]属性 [2]对象通用方法 [3]访问字符方法[4]字符串拼接[5]创建子串方法[6]大小写转换[7]查找子串位置[8]正则匹配方法[9]去除首尾空格[10]字符串比较 前面的话 前面已 ...
- String类型传值以及对象传值
package Virtual; class Stan{ String mm = "hello"; } class Virtual { public static void mai ...
随机推荐
- 使用Eclipse对weblogic进行远程调试
一.环境说明 weblogic12c,linux centOS 6.5,eclipse mars. 二.步骤 1.找到weblogic根目录下user_projects/domains/域名/bin/ ...
- 最全Windows版本jemalloc库(5.2.1)及其使用:包含动态库和静态库、x86版本和x64版本、debug版本和release版本
编写服务器程序时,需要频繁的申请和释放内存,长时间运行会产生大量的内存碎片,这就导致即使当前系统中的闲置内存还足够多,但也无法申请到大的连续可用的内存块,因为此时的物理内存已经千疮百孔像个马蜂窝.此外 ...
- Java学习笔记--面对对象OOP
面向对象编程 OOP 面向对象&面向过程 面向对象编程的本质:以类的方式组织代码,以对象的方法组织数据 面向对象编程的三大特征: 封装 继承 多态 方法 静态方法 通过 static 关键词说 ...
- Docker修改容器中的时间
Docker修改容器中的时间 前言 在公司开发时使用 Docker 创建数据库(SQL Server)的实例十分方便,还原数据库也只要设置好共享文件夹,在 SQL Server Management ...
- ESP8266- AP模式的使用
打算通过该模式,利用手机APP完成配网 • AP,也就是无线接入点,是一个无线网络的创建者,是网络的中心节点.一般家庭或办公室使用的无线路由器就是一个AP. • STA站点,每一个连接到无线网络中的终 ...
- 一起学习PHP中GD库的使用(三)
上篇文章我们已经学习了一个 GD 库的应用,那就是非常常用的制作验证码的功能.不过在现实的业务开发中,这种简单的验证码已经使用得不多了,大家会制作出更加复杂的验证码来使用.毕竟现在的各种外挂软件已经能 ...
- 修改文件权限后,再git pull后提示文件已修改
问题: 从git上面pull下来脚本文件,在Linux上面执行.执行chmod +x 后,如果再次有修改文件,git pull 的提示会终止.每次都要使用 git checkout -- <fi ...
- 初探DispatcherServlet#doDispatch
初探DispatcherServlet#doDispatch 写在前面 SpringBoot其实就是SpringMVC的简化版本,对于request的处理流程大致是一样的, 都要经过Dispatche ...
- 深入剖析 Laravel 服务容器
https://cloud.tencent.com/developer/article/1340400
- [转载]解决虚拟机中Centos7出现错误:Failed to start LSB: Bring up/down networking
1.执行 service network restart 出现以下错误 Restarting network (via systemctl): Job for network.service fai ...