簡體   English   中英

string c_str()與data()

[英]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_strdata時,段列表必須折疊為單個段。

所有以前的提交都是一致的,但我還想補充一點,從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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM