C++ 中的std::string和 C-style string 是兩種不同的字符串想许,前者是標準庫中定義的一個類娶耍,后者是字符數組的別名留瞳。
C-style string:通常都以\0作為結尾胡陪。
std::string:標準中未規(guī)定需要\0作為字符串結尾摸柄。編譯器在實現時既可以在結尾加\0颤练,也可以不加。但是,當通過c_str()或data()(二者在 C++11 及以后是等價的)來把std::string轉換為const char *時嗦玖,會發(fā)現最后一個字符是\0(原因見文末附錄)患雇。
C-style string 中一般不能包含\0字符(因為這個字符被當作表示字符串結束的特殊字符處理了),如果包含這個字符宇挫,那么其后的字符將會被忽略苛吱。即:
char s[] = "ab\0c";
cout << s << endl; // 輸出 ab
而std::string沒有這個限制。即:
std::string s{'a', 'b', '\0', 'c'};
//std::string s = "ab\0c"; // 這里由于是從 C-style string 構造 std::string器瘪,所以仍然會忽略 \0 之后的字符
cout << s << endl; // 輸出 ab c
附錄
通過c_str()或data()(二者在 C++11 及以后是等價的)來把std::string轉換為const char *時翠储,會發(fā)現最后一個字符是\0。想理解這個問題需要一點背景知識:
- std::string 是 std::basic_string<CharT, Traits, Allocator>這個模板的特例std::basic_string<char>橡疼。即模板:
template<
class CharT,
class Traits = std::char_traits<CharT>,
class Allocator = std::allocator<CharT>
> class basic_string;
中的參數CharT為char時的特例援所。
- s.size()會返回std::string中字符的個數,即:
string s{'a', 'b', '\0', 'c'};
cout << s.size() << endl; // 輸出 4
s += '\0';
s += 'd';
cout << s.size() << endl; // 輸出 6
使用[]運算符(即std::basic_string::reference std::basic_string::operator[](size_type pos);)獲取std::string中的字符時欣除,其字符的范圍pos是從0到size()住拭。其中0到size()-1是所存儲的字符,而對于pos == size()有如下規(guī)定:
If pos == size(), a reference to the character with value CharT() (the null character) is returned. For the first (non-const) version, the behavior is undefined if this character is modified.
意思是當訪問s[s.size()]時历帚,會返回CharT()的返回值的引用滔岳,而CharT對于std::string是char,且char()返回的是\000挽牢,所以s[s.size()]會返回\0谱煤。通過c_str()或data()(const CharT* c_str() const;)返回的指針訪問字符串時,其效果為:
Returns: A pointer p such that p + i == &operator[](i) for each i in [0,size()].
即p[s.size()]等價于p + s.size()等價于&s.operator等價于s[s.size()]禽拔,所以會發(fā)現返回值是\0刘离。