兩種最重要的標準庫 string和vector string和vector是兩種最重要的標準庫類型,string表示可變長的字元序列,vector存放的是某種給定類型對象的可變長序列。 一、標準庫類型string 1.定義和初始化string對象:初始化string對象的方式有 string s1 ...
兩種最重要的標準庫---string和vector
string和vector是兩種最重要的標準庫類型,string表示可變長的字元序列,vector存放的是某種給定類型對象的可變長序列。
一、標準庫類型string
1.定義和初始化string對象:初始化string對象的方式有
string s1 預設初始化,s1是一個空串 string s2(s1) s2是s1的副本
string s2=s1 等價於s2(s1),s2是s1的副本
string s3("value") s3是字面值"value"的副本,除了字面值最後的那個空字元外
string s3="value" 等價於s3("value"),s3是字面值"value"的副本
string s4(n,'c') 把s4初始化為由連續n個字元c組成的串
如果使用等號(=)初始化一個變數,實際上執行的是拷貝初始化,編譯器把等號右側的初始值拷貝到心創建的對象中去。與之相反,如果不使用等號,則執行的是直接初始化。
2.string對象上的操作
os<<s 將s寫到輸出流os當中,返回os is>>s 從is中讀取字元串賦給s,字元串以空白分隔,返回is
getline(is,s) 從is中讀取一行賦給s,返回is s.empty() s為空返回true,否則返回false
s.size() 返回s中字元的個數 s[n] 返回s中第n個字元的引用,位置n從0計起
s1+s2 返回s1和s2連接後的結果 s1=s2 用s2的副本代替s1中原來的字元
s1==s2 s1!=s2 如果s1和s2中所含的字元完全一樣,則他們相等;string對象的相等性判斷對字母的大小寫敏感
讀取未知數量的string對象:
#include <iostream>
#include <string> using namespace std; int main() { string word; while(cin>>word) cout<<word<<endl; return 0; }
使用getline()讀取一整行:
getline函數的參數是一個輸入流和一個string對象,函數從給定的輸入流中讀入內容,直到遇到換行符為止(註意換行符也被讀進來了),然後把所讀的
內容存入到那個string對象中去(註意不存換行符)。
#include <iostream> #include <string> using namespace std; int main() { string line; //每次讀入一整行,直到達文件末尾 while(getline(cin,line)) cout<<line<<endl; return 0; }
string的empty和size操作:
empty函數根據string對象是否為空返回一個對應的布爾值,empty也是string的一個成員函數。
#include <iostream> #include <string> using namespace std; int main() { string line; while(getline(cin,line)) //每次讀入一整行,遇到空行直接跳過 if(!line.empty()) cout<<line<<endl; return 0; }
size函數返回string對象的長度(即string對象中字元的個數)
#include <iostream> #include <string> using namespace std; int main() { string line; //每次讀入一整行,輸出其中超過100個字元的行 while(getline(cin,line)) if(line.size()>100) cout<<line<<endl; return 0; }
處理string對象中的字元:使用基於範圍的for語句
範圍for語句:這種語句遍歷給定序列中的每個元素並對序列中的每個值執行某種操作,
for (declaration : expression)
statement
其中,expression部分是一個對象,用於表示一個序列。declaration部分負責定義一個變數,該變數將被用於訪問序列中的基礎元素。每次迭代,
declaration部分的變數會被初始化為expression的下一個元素值。
#include <iostream> #include <string> #include <ctype.h> using namespace std; int main() { string s("hello world!!!"); for (decltype(s.size()) index = 0;index != s.size() && !isspace(s[index]);++index) s[index] = toupper(s[index]); cout << s << endl; /*decltype(s.size()) punct_cnt = 0; for (auto c : s) if (ispunct(c)) ++punct_cnt; cout << punct_cnt << " punctuation characters in " << s << endl;*/ /*for (auto & c : s) c = toupper(c); cout << s << endl;*/ getchar(); return 0; }
二、標準庫類型vector
1. 標準庫類型vector表示對象的集合,其中所有對象的類型都相同。集合中的每個對象都有一個與之對應的索引,索引用於訪問對象。因為vector容納著其他對象,
所以它也被稱作容器。
vector能容納絕大多數類型的對象作為其元素,但是因為引用不是對象,所以不存在包含引用的vector。除此之外,其他大多數(非引用)內置類型和類類型都可
以構成vector對象,甚至組成vector的元素也可以是vector。
2. 定義和初始化vector對象
和任何一種類類型一樣,vector模板控制著定義和初始化向量的方法。
vector<T> v1 v1是一個空vector,它潛在的元素是T類型的,執行預設初始化 vector<T> v2(v1) v2中包含有v1所有元素的副本
vector<T> v2=v1 等價於v2(v1),v2中包含有v1所有元素的副本 vector<T> v3(n,val) v3包含了n個重覆的元素,每個元素的值都是val
vector<T> v4(n) v4包含了n個重覆地執行了值初始化的對象 vector<T> v5{a,b,c...} v5包含了初始值個數的元素,每個元素被賦予相應的初始值
vector<T> v5={a,b,c...} 等價於v5{a,b,c...}
3. vector支持的操作
v.empty() 如果v不含有任何元素,返回真;否則返回假 v.size() 返回v中元素的個數
v.push_back(t) 向v的尾端添加一個值為t的元素 v[n] 返回v中第n個位置上元素的引用
v1=v2 用v2中元素的拷貝替換v1中的元素 v1={a,b,c...} 用列表中元素的拷貝替換v1中的元素
v1==v2 v1和v2相等當且僅當它們的元素數量相同且對應位置的元素值都相同 v1!=v2
4. 向vector對象中添加元素
#include <iostream> #include <vector> using namespace std; int main() { vector<int> v; int a; while (cin >> a ,a!=-1) v.push_back(a); for(auto i : v) cout << i << endl; system("pause"); return 0; }
5. 使用迭代器
使用迭代器可以訪問某個元素,迭代器也能從一個元素移動到另外一個元素。迭代器有有效和無效之分,這一點和指針差不多。有效的迭代器或者指向某個元素,或者
指向容器中尾元素的下一個位置;其他所有情況都屬於無效。這些類型都擁有名為begin和end的成員,其中begin成員負責返回指向第一個元素(或第一個字元)的迭代器。
end成員則負責返回指向容器(或string對象)“尾元素的下一個位置”的迭代器,該迭代器指示的是容器的一個本不存在的“尾後”元素。end成員返回的迭代器常被稱作尾後
迭代器或者簡稱為尾迭代器。特殊情況下如果容器為空,則begin和end返回的是同一個迭代器。
標準容器迭代器的運算符:
*iter 返回迭代器iter所指元素的引用 iter->mem 解引用iter並獲取該元素的名為mem的成員,等價於(*iter).mem
++iter 令iter指示容器中的下一個元素 --iter 令iter指示容器中的上一個元素
iter1==iter2 iter1 != iter2 判斷兩個迭代器是否相等(不相等),如果兩個迭代器指示的是同一個元素或者它們是同一個容器的尾後迭代器,則相等;反之,不相等
#include <iostream> #include <vector> #include <string> #include <ctype.h> using namespace std; int main() { string s("some string"); if (s.begin() != s.end()) { auto it = s.begin(); *it = toupper(*it); } cout << s << endl; system("pause"); return 0; }
#include <iostream> #include <vector> #include <string> #include <ctype.h> using namespace std; int main() { string s("some string"); if (s.begin() != s.end()) { for (auto it = s.begin();it != s.end() && !isspace(*it);++it) *it = toupper(*it); } cout << s << endl; system("pause"); return 0; }
迭代器類型:擁有迭代器的標準庫類型使用iterator和const_iterator來表示迭代器的類型。const_iterator和常量指針差不多,能讀取但不能修改它所指的元素值。
相反,iterator的對象可讀可寫。如果vector對象或string對象是一個常量,只能使用const_iterator;如果vector對象或string對象不是常量,那麼既能使用iterator也能
使用const_iterator。
begin和end運算符:begin和end返回的具體類型由對象是否是常量決定,如果對象是常量,begin和end返回const_iterator;如果對象不是常量,返回iterator。為了
便於得到const_iterator類型的返回值,引入了兩個新函數,分別是cbegin和cend,類似於begin和end,兩個新函數也分別返回指示容器第一個元素或最後元素下一個
位置的迭代器。不同的是,不論vector對象(或string對象)本身是否是常量,返回值都是const_iterator。
#include <iostream> #include <vector> #include <string> #include <ctype.h> using namespace std; int main() { string s("some string"); if (s.begin() != s.end()) for (auto it = s.cbegin();it != s.cend() && !s.empty();++it) cout << *it; cout << endl; system("pause"); return 0; }