1. 程式人生 > >C++中std::string與C-String字元陣列的互相轉換

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

的成員函式,可以參考https://en.cppreference.com/w/cpp/string/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::datastd::basic_string::c_str的作用是一樣的,唯一的不同就是C++98中,data返回的常量字元陣列指標指向的字元陣列不以\0結尾。但是自從C++11起,std::basic_string::datastd::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來完成。

總結

轉換的方法很多,覺得好用方便就行。