C++中std::string與C-String字元陣列的互相轉換
C語言中只有字元陣列這一說法,沒有C++專門封裝的字串類std::string
。而字元陣列C-String以\0
作為結束符。std::string
其實還是儲存了C-String這個指標,只不過不同的編譯期對std::string
中的儲存結構都做了不同的處理,這裡我們不討論std::string
的實現,只關心一件事,那就是C-String和std::string
的相互轉換。
C-String 2 std::string
std::string
的定義是std::basic_string<char>
,因此,重點還是在std::basic_string
。
關於std::basic_string
這之中的一些成員函式就提供了轉換的功能,我們一起來看看。
建構函式
這裡的建構函式包含普通建構函式和賦值建構函式。
普通建構函式
basic_string( const CharT* s,
size_type count,
const Allocator& alloc = Allocator() );
basic_string( const CharT* s,
const Allocator& alloc = Allocator() );
template< class InputIt >
basic_string( InputIt first, InputIt last,
const Allocator& alloc = Allocator() );
std::basic_string
只有這三個普通建構函式與C-String相關,可以看到,這三個建構函式分別接受一個字元指標和字元個數、一個字元指標、[開始字元指標,結束字元指標)。這就是轉換。下面是例子。
std: :string strA("FlushHip");
std::string strB("FlushHip", 5);
std::string strC("FlushHip", "FlushHip" + 8);
賦值建構函式
basic_string& operator=( const CharT* s );
這允許我們可以直接把字元陣列賦值給std::string
。
std::string str = "FlushHip";
assign
basic_string& append( const CharT* s, size_type count );
basic_string& append( const CharT* s );
template< class InputIt >
basic_string& append( InputIt first, InputIt last );
這和普通建構函式的三個函式很類似,一樣的用法,我們可以在空字串後追加C-String來達到轉換的目的。
std::string().append("FlushHip");
std::string().append("FlushHip", 5);
std::string().append("FlushHip", "FlushHip" + 8);
operator+=
basic_string& operator+=( const CharT* s );
std::string str;
str += "FlushHip";
assign
basic_string& assign( const CharT* s,
size_type count );
basic_string& assign( const CharT* s );
template< class InputIt >
basic_string& assign( InputIt first, InputIt last );
和std::string::append
差不多,只不過這裡變成了給std::string
“賦值”,和operator=
的作用是一樣的。
std::str;
str.assign("FlushHip");
str.assign("FlushHip", 5);
str.assign("FlushHip", "FlushHip" + 8);
std::string
2 C-String
在C++中呼叫系統API,而系統API通常需要C-String字元陣列,因此。這裡還是比較重要的。
c_str
const CharT* std::basic_string::c_str() const;
返回std::string
儲存的常量字元陣列指標,這是我們從std::string
轉到const char *
最常用的手段;
返回的字數陣列指標指向的字元陣列以\0
結束。因此[c_str(); c_str() + size()]
都是有效的。
std::string str("FlushHip);
assert(s.size() == std::strlen(s.c_str()));
assert(std::equal(s.begin(), s.end(), s.c_str()));
assert(std::equal(s.c_str(), s.c_str() + s.size(), s.begin()));
assert(0 == *(s.c_str() + s.size()));
const char *pString = str.c_str(); // pString = "FlushHip"
data
const CharT* std::basic_string::data() const;
std::basic_string::data
和std::basic_string::c_str
的作用是一樣的,唯一的不同就是C++98中,data
返回的常量字元陣列指標指向的字元陣列不以\0
結尾。但是自從C++11起,std::basic_string::data
和std::basic_string::c_str
就完全等同了。
copy
size_type std::basic_string::copy( CharT* dest,
size_type count,
size_type pos = 0) const;
如果我們不需要常量字元陣列的指標,那麼,只有重新開一個字元陣列,用std::string::copy
複製了;
既然是複製,那麼就不會複製\0
到新的字元陣列,那麼最後就要自己手動新增\0
,如果開始位置pos > size()
就會丟擲std::out_of_range
異常;
同時,如果count == std::string::npos
,那麼複製的範圍是[pos, size())
。
std::string str("FlushHip");
char arrayString[9];
str.copy(arrayString, 8, 0);
arrayString[8] = '\0'; // arrayString = "FlushHip"
當然,你可以用std::string::c_str
搭配std::memcpy
或者strcpy
來完成。
總結
轉換的方法很多,覺得好用方便就行。