[英]string c_str() vs. data()
我看了幾個地方那之間的區別c_str()
和data()
在STL和其他實現)是c_str()
始終是NULL終止,而data()
不是。 就我在實際實現中看到的而言,它們要么執行相同的操作,要么使用data()
調用c_str()
。
我在這里錯過了什么? 在哪種情況下使用哪一個更正確?
文檔是正確的。 如果要使用空終止字符串,請使用c_str()
。
如果實現者根據c_str()
實現data()
你不必擔心,如果你不需要將字符串空終止,仍然使用data()
,在某些實現中它可能會變成執行比c_str()更好。
字符串不一定必須由字符數據組成,它們可以由任何類型的元素組成。 在這些情況下, data()
更有意義。 我認為c_str()
僅在字符串元素基於字符時才有用。
額外 :在C ++ 11及更高版本中,兩個函數都必須相同。 即data
現在需要以空值終止。 根據cppreference :“返回的數組以空值終止,即data()和c_str()執行相同的功能。”
在C ++ 11 / C ++ 0x中 , data()
和c_str()
不再是不同的。 因此, data()
也需要在結束時具有空終止。
21.4.7.1
basic_string
訪問器[string.accessors]
const charT* c_str() const noexcept;
const charT* data() const noexcept;
1返回:指針p,使得
p + i == &operator[](i)
為[0,size()]
每個i
。
21.4.5 basic_string元素訪問[string.access]
const_reference operator[](size_type pos) const noexcept;
1要求:pos <= size()。 2返回:
*(begin() + pos) if pos < size()
,否則引用類型為T的對象,其值為charT();
參考值不得修改。
即使知道你已經看到它們做同樣的事情,或者.data()調用.c_str(),假設其他編譯器就是這種情況也是不正確的。 您的編譯器也可能會在將來的版本中更改。
使用std :: string的2個理由:
std :: string可用於文本和任意二進制數據。
//Example 1
//Plain text:
std::string s1;
s1 = "abc";
//Example 2
//Arbitrary binary data:
std::string s2;
s2.append("a\0b\0b\0", 6);
在使用字符串作為示例1時,應使用.c_str()方法。
當您使用字符串作為示例2時,您應該使用.data()方法。不是因為在這些情況下使用.c_str()是危險的,但是因為更明確的是您正在使用二進制數據供其他人審閱你的代碼。
使用.data()可能存在陷阱
以下代碼錯誤,可能會導致程序中的段錯誤:
std::string s;
s = "abc";
char sz[512];
strcpy(sz, s.data());//This could crash depending on the implementation of .data()
實現者為什么常常使.data()和.c_str()做同樣的事情?
因為這樣做效率更高。 使.data()返回非空終止的東西的唯一方法是讓.c_str()或.data()復制它們的內部緩沖區,或者只使用2個緩沖區。 具有單個空終止緩沖區始終意味着在實現std :: string時始終只能使用一個內部緩沖區。
它已經得到了回答,有關目的的一些說明:實施自由。
std::string
操作 - 例如迭代,連接和元素變換 - 不需要零終止符。 除非將string
傳遞給期望零終止字符串的函數,否則可以省略它。
這將允許實現使子串共享實際的字符串數據: string::substr
可以在內部持有對共享字符串數據的引用,以及開始/結束范圍,從而避免實際字符串數據的復制(和附加分配)。 實現將推遲復制,直到您調用c_str或修改任何字符串。 如果只涉及所涉及的標志,則不會復制。
(在多線程環境中,copy-on-write實現並不是很有趣,加上典型的內存/分配節省不值得今天更復雜的代碼,所以很少這樣做)。
類似地, string::data
允許不同的內部表示,例如rope(字符串段的鏈表)。 這可以顯着改善插入/更換操作。 再次,當您調用c_str
或data
時,段列表必須折疊為單個段。
所有以前的提交都是一致的,但我還想補充一點,從c ++ 17開始,str.data()返回一個char *而不是const char *
引自ANSI ISO IEC 14882 2003
(C ++ 03標准):
21.3.6 basic_string string operations [lib.string.ops]
const charT* c_str() const;
Returns: A pointer to the initial element of an array of length size() + 1 whose first size() elements
equal the corresponding elements of the string controlled by *this and whose last element is a
null character specified by charT().
Requires: The program shall not alter any of the values stored in the array. Nor shall the program treat the
returned value as a valid pointer value after any subsequent call to a non-const member function of the
class basic_string that designates the same object as this.
const charT* data() const;
Returns: If size() is nonzero, the member returns a pointer to the initial element of an array whose first
size() elements equal the corresponding elements of the string controlled by *this. If size() is
zero, the member returns a non-null pointer that is copyable and can have zero added to it.
Requires: The program shall not alter any of the values stored in the character array. Nor shall the program
treat the returned value as a valid pointer value after any subsequent call to a non- const member
function of basic_string that designates the same object as this.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.