c++ primer plus第16章 string类和标准模板库 笔记

c++ primer plus第16章 string类和标准模板库 笔记


string 类

一. 构造字符串

string类的构造函数

构造函数 举例 描述
string(const chr* s) string one(“Lottery”) 将string对象初始化为s指向的NBTS1
string(size_type n,char c) string(20,’$’) 创建一个包含n个元素的string对象,其中每个元素都被初始化为字符c
string(const string &str) string three(one) 复制构造函数
string() string four 默认构造函数
string(const char*s,size_type n) char alls[]=“something”;string five(alls,5) 将一个string对象初始化s指向的NBTS的前n个字符,及时超过了NBTS结尾
template string (Iter begin,Iter end) string six(alls+6,alls+10); 将string对象初始化为区间[begin,end)内的字符
string(const string&str,string size_type pose=0,size_type n=npos) string seven(four,7,16); 将一个string对象初始化为对象str中从位置pos开始到结尾的字符,或从位置pos开始的n个字符
string(string &&str)noexcept2 将一个string对象初始化为对象str,并可能修改str(移动构造函数)
string(initializer_listil) string comp_lang={‘l’,‘i’,‘s’,‘p’}; 将一个string对象初始化为初始化列表il中的字符
char alls[]="All's well that ends well";
string four(alls,20); //alls[]的前20个字符;
string five(alls+6,alls+10) ;
string six(&five[6],&five[10];

template string (Iter begin,Iter end)
begin 和end类似于指针。但string对象five(对象名)不同于数组名,不会被看作是对象的地址,所以只用 five+6是不管用的, 而five[6]是一个char值,所以
&five[6]是一个地址,因此可以被用作该构造函数的一个参数。

二.string类输入

string stuff;
cin>>stuff; //读取一个单词
getline(cin,stuff);//读取一行,忽略\n
getline(stuff,':');//指定“:”为输入边界

string::nops:string对象的最大允许长度,一般为unsigned int的最大值;

三.使用字符串

  1. 比较:
string snake1=“ ”;
string snake2=“ ”;
char snake3[20]=“ ”;
if(snake1<snake2)
...
if(snake2==snake3)
...
if(snake1!=snake3)
...

2.搜索字符或字符串(find)

方法原型 描述
size_type find(const string &str,size_type pos=0)const; 从字符串pos为止开始,查找子字符串str。如果找到,返回该子字符串首次出现时,其首字符的的索引;否则,返回string::npos
size_type find(const char *s,size_type pos=0)const 从字符串pos为止开始,查找子字符串s。如果找到,返回该子字符串首次出现时,其首字符的的索引;否则,返回string::npos
size_type find(const char*s,size_type pos=0,size_type n) 从字符串pos为止开始,查找子字符串s的前n个字符组成的子字符串。如果找到,返回该子字符串首次出现时,其首字符的的索引;否则,返回string::npos
size_type find( char ch,size_type pos=0)const 从字符串pos为止开始,查找字符ch。如果找到,返回该子字符首次出现时,其首字符的的索引;否则,返回string::npos
refind() 查找子字符串或字符最后一次出现的位置
find_first_of() 查找子字符串或字符首次出现的位置
find_last_of() 查找子字符串或字符最后一次出现的位置
find_first_not_of() 在字符串中查找第一个不包含在参数中的字符

例程

#include 
#include 
#include 
#include 
#include 
using namespace std;
const int NUM = 26;
const string wordlist[NUM] = {"apiary", "beetle", "cereal", "danger",
                              "ensign", "florid", "garage"};

int main()
{
    srand(time(0)); //生成随机数种子
    char play;
    cout << "Will you play a word game?";
    cin >> play;
    while (play == 'y')
    {
        string target = wordlist[rand() % NUM];
        int length = target.length();
        string attempt(length, '-');
        string badchars;
        int guess = 6;
        cout << "Guess my secret word.It has " << length
             << " letters,and you guess\n"
             << "one letter at a time.you get " << guess
             << " wrong guesses.\n";
        cout << "your word: " << attempt << endl;
        while (guess > 0 && attempt != target) //如果剩余次数不为零,且没猜对
        {
            char letter;
            cout << "guess a letter: "; //猜一个字母
            //查看该字符是否已经猜过(attempt 和badchars 中有记录)
            cin.get(letter);
            if (badchars.find(letter) != string::npos || attempt.find(letter) != string::npos)
            {
                cout << "you already guessed that.Try again.\n";
                continue;
            }
            //查找该字母是否在target中,如果不在
            int loc = target.find(letter); //显示该字母在target中的位置
            if (target.find(letter) == string::npos)
            {
                badchars += letter; //把该字母记录到badchars
                cout << "oh,bad guess!\n";
                guess--; //剩余猜测次数减一
            }

            else //如果在target中
            {
                cout << "good guess";
                attempt[loc] = letter;
                //判断该字母在target中是否出现多次,如果出现多次,则都显示出来
                loc = target.find(letter, loc + 1);
                while (loc != string::npos) //没有到target的最后一个字母
                {
                    attempt[loc] = letter;
                    loc = target.find(letter, loc + 1);
                }
            }
            cout << "your word: " << attempt << endl;
            if (attempt != target)
            {
                if (badchars.length() > 0)
                    cout << "Bad choices: " << badchars << endl;
                cout << guess << " bad guesses left \n";
            }
        }
        if (guess > 0)
            cout << "That's right!\n";
        else

            cout << "Sorry ,the word is " << target << ".\n";
        cout << "will you play another?";
        cin >> play;
        play = tolower(play);
    }
    cout << "Bye\n";
    system("pause");
    return 0;
}

四. 其他

capacity()返回当前分配给字符串的内存块大小
reserve()请求内存块的最小长度。
l例如:
empty.capacity();
empty.reserve(50);

智能指针

c++11的智能指针

  1. unique_ptr
    不允许多个指针共享资源,可以用标准库中的move函数转移指针。这个指针所指向的空间只能有它所指向,它存放的地址不许赋值到其他指针去。
  2. shared_ptr
    多个指针共享资源
  3. weak_ptr
    可复制shared_ptr,但其构造或者释放对资源不产生影响

标准模板库

STL 提供了一组表示容器、迭代器、函数对象和算法的模板。

  • 容器:与数组类似,可以存储若干个类型相同的值
  • 迭代器:广义指针,能够便利容器的对象
  • 函数对象:类似于函数的对象,可以是类对象或函数指针
  • 算法:完成特定任务

模板类vector

一. 可对矢量执行的操作
  • size() 返回容器中元素数目
  • swap() 交换两个容器的内容
  • begin()返回一个指向容器中第一个元素的迭代器
  • end() 返回一个表示超过容器尾的迭代器
  • push_back() 将元素添加到矢量末尾。无需了解元素的数目,只要能够取得足够的内存,程序就可以根据需要增加长度。
vector<double>scores;
double temp;
while(cin>>temp &&temp>=0)
	scores.push_back(temp);
  • erase()删除矢量中给定区间的元素,接受两个迭代器参数
    scores.erase(scores.begin(),scores.begin()+2);

  • insert() 接受3个迭代器参数,第一个制定了新元素的插入位置,第二个和第三个定义了被插入区间,该区间通常是另一个容器对象的一部分。
    old_v.insert(old_v.end(),new_v.begin()+1,new_v.end());//在old_v的尾部添加新元素;

  • for_each():接收三个参数,前两个是定义容器中区间的迭代器,最后一个是指向函数的指针。将被指向的函数应用于容器区间的各个元素。被指向的函数不能修改容器元素值。可以用for_each()来代替for循环。
    例如:

vector<Review> ::iterator pr;
for(pr=books.begin();pr!=books.end();pr++)
	show(*pr)
	\\可以替换为:
for_each(books.begin(),books.end(),showreview);
  • Random_shuffle() 接受两个指定区间的迭代器参数,并随机排列该区间的元素。该函数要求容器类允许随机访问。
    random_shuffle(books.begin(),books.end());

  • sort() 该函数要求容器类允许随机访问。
    用法一:当容器能够处理"<"操作时,接受两个定义区间的迭代器参数,对区间元素进行(<)排序操作;当容器不接受时(用户自定义的数据类型),需要用户定义operator<()函数

//用法一:当容器能够处理"<"操作时,接受两个定义区间的迭代器参数,对区间元素进行(<)排序操作
vector<int>coolstuff; 
····
sort(coolstuff.begin(),coolstuff.end());
//当容器不接受时(用户自定义的数据类型),需要用户定义operator<()函数
bool operator<(const Review&r1,const Review&r2)
{
	if(r1.title<re.title)
		return true;
	else if(ri.title==r2.title)
		return true;
	else
		return false;
}
sort(books.begin(),books.end());

用法二:sort()接受三个参数,最后一个是指向要使用的函数(这样可以实现自定义排序)

bool worsethan(const Review&r1,const Review&r2)
{
	if(r1.rating<r2.rating)
		return true;
	else
		return false;
}
sort(books.begin(),books.end(),worsethan);

基于范围的for循环
for_each(books.begin(),books.end(),showreview)
也可替换为:
for(auto x:books) showreview(x);


  1. NBTS:(null-terminated string):表示以空字符串结尾的C风格字符串 ↩︎

  2. noexcept:该关键字告诉编译器,函数中不会发生异常,这有利于编译器对程序做更多的优化。
    如果在运行时,noexecpt函数向外抛出了异常(如果函数内部捕捉了异常并完成处理,这种情况不算抛出异常),程序会直接终止,调用std::terminate()函数,该函数内部会调用std::abort()终止程序。 ↩︎

你可能感兴趣的:(c++学习)