Answers:
该文档是正确的。使用c_str()
,如果你想有一个空结束的字符串。
如果实现者恰好实现data()
了c_str()
您不必担心的实现,则仍然可以使用,data()
如果您不需要以null结尾的字符串,那么在某些实现中,它可能会比c_str()更好。
字符串不一定必须由字符数据组成,它们可以由任何类型的元素组成。在那些情况下data()
更有意义。c_str()
在我看来,仅当字符串的元素基于字符时才真正有用。
附加:从C ++ 11开始,两个函数必须相同。即data
现在需要为空终止。根据cppreference的描述:“返回的数组以null结尾,即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,这样in 中
p + i == &operator[](i)
的每个指针。i
[0,size()]
21.4.5 basic_string元素访问[string.access]
const_reference operator[](size_type pos) const noexcept;
1要求:pos <= size()。2返回:
*(begin() + pos) if pos < size()
,否则charT();
将不修改对值为T的T类型对象的引用。
std::string
分配额外char
的空间'\0'
。当你这样做std::string s("\0");
,既s.data()[0]
和s.data()[1]
保证,以评估为0
甚至知道您已经看到它们执行相同的操作,或者.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()返回不以null结尾的东西的唯一方法是使.c_str()或.data()复制其内部缓冲区,或者仅使用2个缓冲区。拥有单个以null终止的缓冲区总是意味着在实现std :: string时,您始终只能使用一个内部缓冲区。
它已经得到答复,并有以下目的说明:执行自由。
std::string
操作(例如迭代,串联和元素突变)不需要零终止符。除非将传递string
给期望终止字符串为零的函数,否则可以将其省略。
这将允许实现使子字符串共享实际的字符串数据:string::substr
可以在内部保存对共享字符串数据的引用以及起始/结束范围,从而避免了实际字符串数据的复制(和其他分配)。该实现将推迟副本,直到您调用c_str或修改任何字符串为止。如果仅阅读所涉及的信息,将不会复制任何内容。
(在多线程环境中,写时复制实现不是很有趣,再加上今天节省的内存/分配并不值得更复杂的代码,因此很少这样做)。
同样,string::data
允许使用不同的内部表示形式,例如,绳索(字符串段的链接列表)。这可以显着改善插入/替换操作。同样,当您调用c_str
或时,必须将细分列表折叠到单个细分中data
。
引用自ANSI ISO IEC 14882 2003
(C ++ 03 Standard):
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.
.data()
,因此它们不再等效于非常量字符串。