複製鏈接
請複製以下鏈接發送給好友

string類

鎖定
C++javaVB等編程語言中的名詞。 在javaC#中,String類是不可變的,對String類的任何改變,都是返回一個新的String類對象
string>C++標準程序庫中的一個頭文件,定義了C++標準中的字符串的基本模板類std::basic_string及相關的模板類實例
中文名
string類
概    念
編程語言中的名詞
屬    性
學術名詞
學    科
計算機科學

string類介紹

模板類實例
std::basic_string的模板實參
string
char
wstring
wchar_t
u16string
char16_t(C++11新增)
u32string
char32_t(C++11新增)
其中的string是以char作為模板參數的模板類實例,把字符串的內存管理責任由string負責而不是由編程者負責,大大減輕了C語言風格的字符串的麻煩。
std::basic_string提供了大量的字符串操作函數,如比較、連接、搜索、替換、獲得子串等。並可與C語言風格字符串雙向轉換。std::basic_string屬於C++ STL容器類,用户自定義的類也可以作為它的模板參數,因此也適用C++ STL Algorithm庫。
string本質上是以字符作為元素的vector特化版本;不存在0字符結尾這個概念,能裝入'\0'這種數據。

string類std::basic_string類模板

std::basic_string類模板存儲且操縱類似char的對象的序列。該對象類型的性質由特性類模板std::char_traits的實例來提供,並作為std::basic_string的第二個模板參數 [1] 
C++11標準規定:basic_string的元素是連續存儲的。即對於basic_string s,有:&*(s.begin() + n) == &*s.begin() + n,其中n屬於[0, s.size())。換句話説,指向s[0]的指針即為指向CharT[]數組的首元素指針。C++11已經禁止了寫入時複製(copy-on-write)的實現,因為存在多線程安全問題。一般都採用了小字符串優化(SSO)實現,如Visual C++:
union _Bxty { // storage for small buffer or pointer to larger one _Elem _Buf[_BUF_SIZE]; _Elem *_Ptr; } _Bx; size_type _Mysize; // current length of stringsize_type _Myres; // current storage reserved for string
GCC從版本5開始,std::string不再採用COW策略。
C++17標準規定,basic_string是AllocatorAwareContainer, SequenceContainer與ContiguousContainer。

string類模板參數

  • CharT - 字符類型
  • Traits - 字符的特性類
  • Allocator 內部存儲的分配器類

string類成員類型

  • traits_type 模板參數Traits
  • value_type 即Traits::char_type
  • allocator_type模板參數Allocator
  • size_type 即Allocator::size_type。C++11改為std::allocator_traits<Allocator>::size_type
  • difference_type即Allocator::difference_type。C++11改為std::allocator_traits<Allocator>::difference_type
  • reference 即Allocator::reference。C++11改為value_type&
  • const_reference 即Allocator::const_reference。C++11改為const value_type&
  • pointer 即Allocator::pointer。C++11改為std::allocator_traits<Allocator>::pointer
  • const_pointer 即Allocator::const_pointer。C++11改為std::allocator_traits<Allocator>::const_pointer
  • iterator 屬於RandomAccessIterator
  • const_iterator 屬於Constant random access iterator
  • reverse_iterator 即std::reverse_iterator<iterator>
  • const_reverse_iterator 即std::reverse_iterator<const_iterator>

string類成員函數

下面列出所有成員函數,其中string是std::basic_string<T>的簡寫:
  • 構造表示
    • string::string(構造)
    • string::~string(析構)
    • string::operator=- 賦值
    • string::assign–賦值
    • string::get_allocator–獲得內存分配器
  • 字符訪問
    • string::at–訪問特定字符,帶邊界檢查
    • string::operator[]–訪問特定字符
    • string::front–訪問第一個字符
    • string::back–訪問最後一個字符
    • string::data–訪問基礎數組,C++11 後與 c_str() 完全相同
    • string::c_str–返回對應於字符串內容的 C 風格零結尾的只讀字符串
    • string::substr–以子串構造一個新串;參數為空時取全部源串
  • 迭代器
    • string::begin–獲得指向開始位置的迭代器
    • string::end–獲得指向末尾的迭代器
    • string::rbegin–獲得指向末尾的逆向迭代器
    • string::rend–獲得指向開始位置的逆向迭代器
    • string::cbegin–獲得指向開始位置的只讀迭代器
    • string::cend–獲得指向末尾的只讀迭代器
    • string::crbegin–獲得指向末尾的逆向只讀迭代器
    • string::crend–獲得指向開始位置的逆向只讀迭代器
  • 容量
    • string::empty–檢查是否為空
    • string::size–返回數據的字符長度
    • string::length–返回數據的字符長度,與 size() 完全相同
    • string::max_size–返回可存儲的最大的字節容量,在 32 位 Windows 上大概為 43 億字節。
    • string::reserve–改變 string 的字符存儲容量,實際獲得的存儲容量不小於 reserve 的參數值。
    • string::capacity–返回當前的字符存儲容量
    • string::shrink_to_fit(C++11新增)–降低內存容量到剛好
  • 修改器
    • string::clear–清空內容
    • string::insert–插入字符或字符串。目標 string 中的插入位置可用整數值或迭代器表示。如果參數僅為一個迭代器,則在其所指位置插入0值。
    • string::erase–刪除 1 個或 1 段字符
    • string::push_back–追加 1 個字符
    • string::pop_back–刪除最後 1 個字符,C++11 標準引入
    • string::append–追加字符或字符串
    • string::operator+=–追加,只有一個參數——字符指針、字符或字符串;不像 append() 一樣可以追加參數的子串或若干相同字符
    • string::copy–拷貝出一段字符到 C 風格字符數組;有溢出危險
    • string::resize–改變(增加或減少)字符串長度;如果增加了字符串長度,新字符缺省為 0 值
    • string::swap–與另一個 string 交換內容
    • string::replace–替換子串;如果替換源數據與被替換數據的長度不等,則結果字符串的長度發生改變
  • 搜索
    • string::find–前向搜索特定子串的第一次出現
    • string::rfind–從尾部開始,後向搜索特定子串的第一次出現
    • string::find_first_of–搜索指定字符集合中任意字符在 *this中的第一次出現
    • string::find_last_of–搜索指定字符集合中任意字符在 *this 中的最後一次出現
    • string::find_first_not_of–*this 中的不屬於指定字符集合的首個字符
    • string::find_last_not_of–*this 中的不屬於指定字符集合的末個字符
    • string::compare–與參數字符串比較

string類常量值

    • string::npos–表示“未找到”,值為static const unsigned -1

string類非成員的有關的全局函數

    • std::operator+–字符串連接
    • std::operator!=–不等比較
    • std::operator==–相等比較
    • std::operator<–小於比較
    • std::operator<=–小於等於比較
    • std::operator>–大於比較
    • std::operator>=–大於等於比較
    • std::operator<<–字符串內容寫到輸出流中
    • std::operator>>–從輸入流中讀取一個字符串
    • std::getline–從istream中讀入一行或一段字符到string中
    • std::swap–交換兩個string的內容。是std::swap算法針對std::basic_string的特化版本
    • std::stoi–字符串轉為整形
    • std::stol–字符串轉為長整形
    • std::stoll–字符串轉為長長整形
    • std::stoul–字符串轉為無符號長整形
    • std::stoull–字符串轉為無符號長長整形
    • std::stof–字符串轉為單精度浮點形
    • std::stod–字符串轉為雙精度浮點形
    • std::stold–字符串轉為長雙精度浮點形
    • std::to_string–整型、無符號整型、浮點型轉化為string
    • std::to_wstring–整型、無符號整型、浮點型轉化為wstring
    • std::hash<std::string>–計算hash值
    • std::hash<std::wstring>–計算hash值
    • std::hash<std::u16string>–計算hash值
    • std::hash<std::u32string>–計算hash值

string類字面量

C++14標準定義瞭如下的std::basic_string字面量
  • string operator "" s(const char *str, std::size_t len);
  • u16string operator "" s(const char16_t *str, std::size_t len);
  • u32string operator "" s(const char32_t *str, std::size_t len);
  • wstring operator "" s(const wchar_t *str, std::size_t len);
示例:
  • #include<string>#include<iostream>intmain(){usingnamespacestd::string_literals;std::strings2="abc\0\0def";//formsthestring"abc"std::strings1="abc\0\0def"s;//formthestring"abc\0\0def"std::cout<<s1.size()<<std::endl;//output8std::cout<<s2<<std::endl;std::cout<<s1<<std::endl;}

string類構造hash值的函數

C++11標準引入了4個std::hash函數模板的特化。用於以string為鍵值的hash定址。
  • template<> struct hash<std::string>;
  • template<> struct hash<std::wstring>;
  • template<> struct hash<std::u16string>;
  • template<> struct hash<std::u32string>;

string類std::char_traits類

char_traits是一個traits類模板。用於抽象出給定字符類型的字符特性與字符串操作。char_traits用於明確(explicit)實例化一個std::basic_string類模板。
  • 成員類型
    • char_type CharT
    • int_type 可以保持char_type以及EOF的值的整數類型
    • off_type 實現定義
    • pos_type 實現定義
    • state_type 實現定義
  • 成員函數
    • assign[static]賦值一個字符
    • eq[static] 比較兩個字符相等
    • lt[static] 比較兩個字符小於
    • move[static] 移動一個字符序列到另一個字符序列
    • copy[static] 複製一個字符序列
    • compare[static]詞典序比較兩個字符序列
    • length[static]返回一個字符序列的長度
    • find[static] 在一個字符序列中找到一個字符
    • to_char_type[static]轉化整型值到相等的char_type
    • to_int_type[static] 轉化char_type到相等的整型值
    • eq_int_type[static] 比較兩個整型值
    • eof[static] 返回eof值
    • not_eof[static]檢查一個字符是否為eof值
例如,如果需要定義“兩個字符相等”當且僅當“兩個字符的大寫形式相等”,就可以在std::char_traits<char>之上派生定義一個類,重載定義eq、lt、compare、find四個靜態成員函數。再用此特性類作為第二個模板參數去實例化std::basic_string類模板。

string類用法

#include <iostream>#include <string>int main(){    std::string foo = "fighters";    std::string bar = "stool";    // "!=" compares string contents for inequality, even though they are different objects.    if(foo != bar)    {        std::cout << "The strings are different." << std::endl;    }    // Prints "stool fighters" by creating a temporary object, which is automatically freed.    std::cout << bar + " " + foo << std::endl;    return 0;}/* Output: The strings are different. stool fighters*/
由於字符串的拷貝操作與其字節長度成比例,是O(n)量級。且創建字符串的臨時棧對象的成本開銷。因此string一般作為常量引用(reference-to-const)以避免不必要的拷貝:
void print_the_string(const std::string& str){    std::cout << str;}
c_str()成員函數返回string類的C語言風格字符串(即ASCII-零串)的指針,用於C語言字符串的互操作。如果不需要零結尾的字符串,那麼成員函數data()返回不一定是0結尾的字符串的內存地址。

string類剖析

能夠準確無誤地編寫出String類的構造函數拷貝構造函數賦值函數和析構函數的面試者至少已經具備了C++基本功的60%以上!在這個類中包括了指針成員變量m_data,當類中包括指針類成員變量時,一定要重載其拷貝構造函數、賦值函數和析構函數,這既是對C++程序員的基本要求,也是《Effective C++》中特別強調的條款。仔細學習這個類,特別注意加註釋的得分點和加分點的意義,這樣就具備了60%以上的C++基本功!
參考資料
  • 1.    李斌[1], 王睿[1], 何成芊[1]. 深入探討Java中的String類[J]. 湖南郵電職業技術學院學報, 2009(3).