1.学习string类
C语言中,字符串是以'\0'结尾的一些字符的集合,为了操作方便,C标准库中提供了一些str系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。
标准库中的string类
1.auto和范围for
首先我们在这里先说明一下迭代器的使用,具体之后会说明。
iterator
这个是一个类似指针的东西,基本在各个类上都有它的存在
string::iterator it=s.begin();
此时it指向的位置位于字符串的起点。
while (it != s.end())
{
cout << *it << " ";
++it;
}
cout << endl;
此时使用while循环便可遍历数组。 这也是一种遍历字符串的方式。
auto的定义
在早期C/C++中auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,后来这个 不重要了。C++11中,标准委员会变废为宝赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得。
auto的语法
用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加&
当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际 只对第一个类型进行推导,然后用推导出来的类型定义其他变量。
auto不能作为函数的参数,可以做返回值,但是建议谨慎使用
auto不能直接用来声明数组
auto如果想要在使用过程中改变所指向的内容,就必须加上&。
范围for
对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此 C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范围 内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。
范围for可以作用到数组和容器对象上进行遍历
范围for的底层很简单,容器遍历实际就是替换为迭代器,这个从汇编层也可以看到。
例如
for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i)
{
cout << array[i] << endl;
}
在使用C语言的时候,这样写法较为繁琐,但是使用了auto之后
for (auto e : array)
cout << e << " " << endl;
代码变得较为简洁。
string常用的接口
string常见的构造
1.string():它的作用是构造空字符串。
string s1;
2.string(const char* s):用C-string来构造string类对象。
string s2("hello world");
3.string(const string&s):拷贝构造函数。
string s3(s2);
string类对象的容量操作
1.size():返回字符串有效字符长度
2.length():返回字符串有效字符长度
size()与length()方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()。
3.capacity():返回空间总大小
4.empty(): 检测字符串释放为空串,是返回true,否则返回false
5.clear() : 清空有效字符,clear()只是将string中有效字符清空,不改变底层空间大小。简单来讲就是只清除数据,不清除容量。
6 reserve(size_t n=0):如果 n 大于当前字符串容量,则该函数会导致容器将其容量增加到 n 个字符(或更大),若给定n小于当前字符串容量,则会保持原容量不变
7.resize
void resize (size_t n);void resize (size_t n, char c);
resize(size_t n) 与 resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)用0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
string类对象的访问及遍历操作
1.operator[]:返回pos位置的字符,和数组类似,[]用于访问string类的第几个字符的位置。
2.begin和end:begin获取第一个字符的迭代器 + end获取最后一个字符下一个位置的迭代器
3.rbegin和rend:和begin和end刚好反过来,用于倒序遍历
string类对象的修改操作
1.push_back(char c) :在字符串后尾插字符c。
2.append(const string& str):在字符串后追加一个字符串,功能与push_back(char c)类似
3.operator+=:功能与上面两个接口相似,不过使用更加方便,上面两个接口存在时间较久,存在的目的只是为了兼容之前的版本。
4.c_str:返回C格式字符串,它提供了一种将 std::string
对象转换为 C 风格字符串(即以 null 结尾的字符数组)的方式。
5.insest(size_t pos, size_t count, char ch),(size_t pos,const char* s)等等:它的作用是在pos位置插入count个字符ch或者在pos位置插入字符串s等等。
6.erase(size_ type pos,size_type len =npos):它能够从pos位置开始删除len个数据,如果在传参的时候len过大,erase也只会删除到/0的位置。
7.replace(size_t pos, size_t len, const std::string& str):从pos位置开始的len个字符替换成str。如果 len 的值超过了从指定位置到字符串末尾的字符数,则只会替换从指定位置到字符串末尾的字符。
8.find(const char* s, size_t pos = 0):find的返回类型是size_t,返回的是该字符在字符串中的下标,从字符串pos位置开始往后找字符s,返回该字符在字符串中的位置。
9.rfind:用法与find类似,不过rfind是从末尾开始查找的,它的作用在于查找文件后缀等等。
10substr(size_t pos = 0, size_t len = npos):用于从字符串中提取子字符串,pos为开始提取的位置,len为提取的长度,
- 如果
pos
超过字符串的长度,则会引发std::out_of_range
异常。 - 如果
len
超过从pos
开始到字符串末尾的长度,则substr
会提取到字符串末尾,而不会引发异常。
std::string str = "Hello, world!";
std::string sub1 = str.substr(7);
std::cout << "sub1: " << sub1 << std::endl;
11.find_first_of:它在字符串中查找指定字符集合中的任意一个字符的第一次出现位置。
size_t pos = str.find_fast_of(chars);
12 find_last_of:用于查找字符串中指定字符集合中的任意字符最后一次出现的位置。
size_t pos = str.find_last_of(chars);
string类非成员函数
1.getline:在面对输入的字符串中存在空格的情况,空格及之后的内容被存储到缓冲区中,此时string的接口读取不到之后的内容,此时使用geiline能够避开这种情况,它能默认将空格存储进字符串中。
std::getline (std::cin,name);