【C++學習筆記】標準庫類型string

版權聲明:本文爲博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/LAW_130625/article/details/78629062

  標準庫類型string表示可變長的字符序列,使用string類型必須先包含string頭文件,string定義在命名空間std。

#include <string>
using std::string

一、定義和初始化string對象
  一個類可以定義很多種初始化對象的方式,它們之間都有一定的區別,比如初始值的數量不同,或初始值的類型不同,下面爲初始化string對象常用的方式:

string s1;                 //默認初始化,s1是一個空字符串
string s2(s1);             //s2是s1的副本
string s2 = s1;            //同上
string s3("hi");           //s3是該字符串字面值的副本,除了字面值最後那個空字符
string s3 = "hi";          //s3是字面值"hi"的副本
string s4(10,'c');         //s4的內容是cccccccccc

1.1 直接初始化和拷貝初始化
  如果使用等號(=)初始化一個變量。實際上執行的是拷貝初始化(copy initialization),編譯器把等號右側初始值拷貝到新創建的對象中去,反之不適應等號,則還行的是直接初始化。

string s5 = "hiya";          //拷貝初始化
string s6("hiya");           //直接初始化
string s7(10,'c');           //直接初始化
string s8 = string(10,'c');  //拷貝初始化

二、string對象上的操作
2.1 讀寫string對象
  如同使用標準庫iostream來讀寫int、double等內置類型的值,可以使用IO操作符來讀寫string對象:

#include <iostream>
#include <string>
using namespace std;
int main()
{
   string s;
   cin >> s;
   cout << s << endl;
   return 0;
}

  在執行讀取操作時,string對象會自動忽略開頭的空白(即空格符、換行符、製表符等),如果程序輸入的是” hello world! “,則輸出將是“hello”,輸出結果沒有任何空格。
  下面的程序可以用讀取位置數量的string對象:

int main()
{
   string word;
   while(cin >> word)
      cout << word << endl;
   return 0;
}

2.2 使用getline讀取一整行
  如果希望在最終得到的字符串中保留輸入的空白符,那麼應該使用getline函數代替原來的>>運算符,getline函數的參數是一個輸入流和一個string對象,函數從給定的輸入流中讀取內容,知道遇到換行符爲止(換行符也被讀進來),然後把所讀內容存到那個string對象中去(不含換行符),即getline函數一遇到換行符就借書讀取操作並返回結果,如果一開始就是換行符,那麼所得結果是個空string。
  因爲getline也會返回它的流參數,所以可以使用getline的結果作爲條件,下列程序可以一次輸出一整行:

int main()
{
   string line;
   while(getline(cin,line))
      cout << line << endl;
   return 0;
}

  上面使用endl來結束當前行並刷新顯示緩衝區,另外觸發getline函數返回的那個換行符實際上被丟棄了,所以得到的string對象不包含換行符。

2.3 string的empty和size、及size返回類型
  empty函數根據string對象是否爲空返回一個對應的布爾值:

while (getline(cin,line))
   if (!line.empty())
      cout << line << endl;

  size函數返回string對象的長度,即string對象中的個數,下面用size函數輸出長度超過80個字符的行:

string line;
while(getline(cin,line))
   if (line.size() > 80)
      cout << line << endl;

  size函數返回的是一個string::size_type類型的值,並且這是一個無符號類型的值,即所有存放string類的size函數返回值的變量都是string::size_type類型的,因爲size函數返回時一個無符號整型數,所以混用帶符號和無符號數可能產生意想不到的結果,假如n是具有負值的int,那麼s.size()

string st1 = (10,'c'),st2;   //st1爲cccccccccc,st2位一個空字符串
st1 = st2;                   //st1和st2都是空字符串

  兩個string對象相加得到一個新的string對象,其內容是把左側的運算對象與右側的運算對象串接而成:

string s1 = "hello, ", s2 = "world\n";
string s3 = s1 + s2;          //s3的內容是hello,world\n
s1 += s2;                     //等價於s1 = s1 + s2

  標準庫允許把字符字面值和字符串字面值轉換成string對象,所以在需要string對象的地方就可以使用這兩種字面值來替代:

string s1 = "hello", s2 = "world";
string s3 = s1 + ", " + s2 + '\n';

  需要注意的是當把string對象和字符字面值及字符串字面值混在一條語句時,必須確保每個加法運算符的兩側的運算對象至少有一個是string:

string s4 = s1 + ", ";          //正確,把一個string對象和一個字面值相加
string s5 = "hello" + ", ";     //錯誤,兩個運算對象都不是string s6 = s1 + ", " + "word"; //正確,前面兩項相加的結果是一個string對象

  爲了與C兼容,C++語言中的字符串字面值並不是標準庫類型string的對象,即字符串字面值與string是不同的類型。

三、處理string對象中的字符
3.1 使用基於範圍的for語句
  如果需要對string對象中的每個字符進行操作,那麼可以使用範圍for語句,其語法形式爲:

for (declaration: expression)
   statement

  其中expression部分是一個對象,用於表示一個序列,declaration部分負責定義一個變量,該變量將被用於訪問序列中的基礎元素,每次迭代,declaration部分的變量會被初始化爲expression部分的下一個元素值。

string s("some string!!!");
decltype(s.size()) punct_cnt = 0;
for (auto c : s)              //對於str中的每個字符
   if (ispunct(c))            //判斷其是否爲標點符號
      ++punct_cnt;
 cout << punct_cnt << endl;   //輸出符號個數 

  如果需要改變string對象中字符的值,那麼必須把循環變量定義成引用類型,引用只是給定對象的別名,因此當使用引用作爲循環控制變量時,這個變量實際上被依次綁定到了序列的每個元素上,使用這個引用,就可以改變它綁定的字符。

string s("hello world!!!");
for (auto &c : s)              //對於s中的每個字符(注意c是引用)
   c = toupper(c)              //c是一個引用,將改變s中字符的值,即換成大寫
cout << s << endl;

3.2 使用下標處理string對象
  下標運算符([ ])接收的輸入參數是string::size_type類型的值,這個參數表示要訪問的字符的位置,返回值是該位置上字符的引用,string對象的下標從0計起,需要注意使用下標時必須確保其在合理範圍之內。

for (decltype(s.size()) index = 0;index != s.size();++index)
   s[index] = toupper(s[index]);

參考文獻:
①C++ Primer 第五版。

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