C++ primer 第五版 第三章 課後練習

string類的輸入字符和getline函數分別是如何處理空白字符的

標準庫string的輸入運算符自動忽略字符串開頭的空白(包括空格符、換行符、製表符等),從第一個真正的字符開始讀起,直到遇見下一處空白爲止。

getline可保留輸入時的空白,直到遇到換行符爲止,此時換行符也被讀進來,但是並不存儲在最後的字符串中。

小貼士:

cin.clear();//更改cin的狀態標識符
cin.sync();//清除緩衝區數據流

使用範圍for語句將字符串內的所有字符用x代替

#include<iostream>
#include<string>

using namespace std;

int main()
{
    cout << "請輸入一段字符串,可以包含空格" << endl;
    string s;
    getline(cin , s);
    for(auto &c : s)//c必須定義成引用類型,否則無法修改字符串的內容
    {
        c = 'X';
    }
    cout << s << endl;
}

讀入一個包含標點符號的字符串,輸出去除標點符號的剩餘部分

#include<iostream>
#include<string>
#include<cctype>

using namespace std;

int main()
{
    string s;
    cout << "請輸入一串字符串,最好包含標點符號:" << endl;
    getline(cin , s);
    for(auto c : s)
    {
        if(!ispunct(c))
            cout << c << " " ;
    }
    cout << endl;
    return 0;
}

附錄:cctype頭文件

定義和初始化vector對象

從cin讀入一組詞並把它們存入一個vector對象,然後設法把所有詞改寫爲大寫形式。輸出改變後的結果,每個詞佔一行。

#include<iostream>
#include<vector>
#include<string>

using namespace std;

int main()
{
    vector<string> vString;     //元素類型爲string的vector對象
    string s;                   //記錄用戶的輸入值
    char cont = 'y';             //與用戶交互,決定是否繼續
    cout << "請輸入第一個詞:" << endl;
    while(cin >> s)
    {
        vString.push_back(s);   //向vector對象中添加元素
        cout << "您要繼續嗎(y or n)?" << endl;
        cin >> cont;
        if(cont != 'y' && cont != 'Y')
            break;
        cout << "請輸入下一個詞:" << endl;
    }
    cout << "轉換後的結果是:" << endl;
    for(auto &mem : vString)    //使用範圍for循環遍歷vString中的每個元素
    {
        for(auto &c : mem)      //使用範圍for循環遍歷mem中的每個字符
            c = toupper(c);     //改寫爲大寫形式
        cout << mem <<endl;
    }
    return 0;
}

讀入一組整數並把他們存入一個vector對象,將每對相鄰整數的和輸出。

#include<iostream>
#include<vector>

using namespace std;

int main()
{
    vector<int> vInt;
    int iVal;
    cout << "請輸入一組數字:" << endl;
    while(cin >> iVal)							//按ctrl+z結束輸入
        vInt.push_back(iVal);
    if(vInt.size() == 0)
    {
        cout << "沒有輸入數字" << endl;
        return -1;
    }
    cout << "相鄰兩項的和是:" << endl;
    for(decltype(vInt.size()) i = 0; i < vInt.size()-1; i += 2)
    {
        cout << vInt[i] + vInt[i+1] << " ";     //求相鄰兩項的和
        if((i + 2) % 10 == 0)					//每行輸出5個數字
            cout << endl;
    }
    if(vInt.size() % 2 !=0)						//如果元素數是奇數,單獨處理最後一個元素
        cout << vInt[vInt.size() - 1];
    return 0;
}

編寫一段程序,創建一個含有10個整數的vector對象,然後使用迭代器將所有元素的值都變成原來的兩倍,輸出

#include<iostream>
#include<vector>
#include<ctime>
#include<cstdlib>

using namespace std;

int main()
{
    vector<int> vInt;
    srand((unsigned)time(NULL));    //生成隨機數種子
    for(int i = 0; i < 10; i++)     //循環10次
    {
        //每次循環生成一個1000以內的隨機數並添加到vInt中
        vInt.push_back(rand() % 1000);
    }
    cout << "隨機生成的10個數是:" << endl;
    //利用常量迭代器讀取原始數據
    for(auto it = vInt.cbegin(); it != vInt.cend(); it++)
    {
        cout << *it << " ";          //輸出當前數字
    }
    cout << endl;
    cout << "翻倍後的10個數字是:" << endl;
    //利用非常亮迭代器修改vInt內容並輸出
    for(auto it = vInt.begin(); it != vInt.end(); it++)
    {
        *it *= 2;
        cout << *it << " ";         //輸出當前數字
    }
    cout << endl;
    return 0;
}

小貼士:srand和rand()配合使用產生僞隨機數序列。
rand函數在產生隨機數前,需要系統提供的生成僞隨機數序列的種子,rand根據這個種子的值產生一系列隨機數。
如果系統提供的種子沒有變化,每次調用rand函數生成的僞隨機數序列都是一樣的。
srand(unsigned seed)通過參數seed改變系統提供的種子值,從而可以使得每次調用rand函數生成的僞隨機數序列不同,從而實現真正意義上的“隨機”。只有seed變,產生的隨機序列纔會變。
通常可以利用系統時間來改變系統的種子值,即srand(time(NULL)),可以爲rand函數提供不同的種子值,進而產生不同的隨機數序列。
小貼士:C++沒有定義兩個迭代器的加法運算,即直接將兩個迭代器相加沒有意義,定義了迭代器的減法運算(同一容器),定義了迭代器與整數的加減法運算。指針的算術運算與vector類似,也可以執行遞增、遞減、比較、與整數相加、兩個指針相減等操作。

相比vector,數組的缺點:(1)都能存放類型相同的對象,且對象本身沒有名字,需要通過其所在位置訪問。(2)數組大小不固定,不能隨意向數組中增加額外的元素。(3)數組不能用size,字符數組可以用strlen,其他數組只能用sizeof(array)/sizeof(array[0])的方式計算數組的維度。

比較兩個數組是否相等,用vector改寫

#include<iostream>
#include<ctime>
#include<cstdlib>

using namespace std;

int main()
{
    const int sz = 5;                 //常量sz作爲數組的維度
    int a[sz], b[sz], i;
    srand((unsigned) time(NULL));     //生成隨機數種子
    //通過for循環爲數組元素賦值
    for(i = 0; i < sz; i++)
        //每次循環產生一個10以內的隨機數並添加到a中
        a[i] = rand() % 10;
    cout << "系統數據已經生成,請輸入你猜測的5個數字(0~9),可以重複:" << endl;
    int uVal;
    //通過for循環爲數組元素賦值
    for(i = 0; i < sz; i++)
        if(cin >> uVal)
            b[i] = uVal;
    cout << "系統生成的數據是:" << endl;
    for(auto val : a)
        cout << val << " ";
    cout << endl;
    cout << "你猜測的數據是:" << endl;
    for(auto val : b)
        cout << val << " ";
    cout << endl;
    int *p = begin(a), *q = begin(b);  //定義 分別令p,q指向a和b的首元素
    //C++ forbids comparison between pointer and integer   while(*p != end(a) && *q != end(b))
    while(p != end(a) && q != end(b))//p,q爲指針本身 
    {
        if(*p != *q)
            cout << "抱歉,猜測數據與原數據不等" << endl;
            return -1;
        p++;
        q++;
    }
    cout << "全部猜對" << endl;
    return 0;
}

小貼士:C++不允許使用一個數組初始化另一個數組,也不允許使用vector對象直接初始化數組,允許使用使用數組來初始化vector對象。 vector<int> vInt(begin(a), end(a)); //a爲數組

注意練習3.43,3.44,3.45的對比

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章