std::string 的 strlen(str.c_str()) 和 str.length() 之间的区别

Difference between strlen(str.c_str()) and str.length() for std::string

作为一种隐含的理解,我一直认为std::string的每个实现都必须满足每个字符串str.

strlen(str.c_str()) == str.length()

C++ 标准对此有何规定? (是吗?)

背景:至少Visual C++和gcc附带的实现没有这个属性。考虑这个例子(参见 here for a live example):

// Output:
// string says its length is: 13
// strlen says: 5
#include <iostream>
#include <cstring>
#include <string>

int main() {
  std::string str = "Hello, world!";
  str[5] = 0;
  std::cout << "string says its length is: " << str.length() << std::endl;
  std::cout << "strlen says: " << strlen(str.c_str()) << std::endl;
  return 0;
}

当然是str不注意的写操作导致了"the problem"。但这不是我的问题。我想知道标准对这种行为有何看法。

您的理解有误。有点。

std::string 可能包含值为 '[=12=]'char;当你提取一个 C 字符串时,除了扫描 [=13=]s 之外,你无法知道它有多长,这必然不能解释 "binary data".

这是 strlen 的限制,std::string "fixes" 通过实际记住此元数据作为它知道已封装的 char 的计数。

标准实际上不需要 "say" 任何相关内容,除了 std::string::length 为您提供字符串长度,无论您插入的 char 的值是多少到字符串中,即不禁止插入 '[=12=]'。相比之下,strlen 的定义是告诉你有多少 char 存在到下一个 [=13=],这是一个根本不同的定义。

没有明确的措辞,因为没有必要。如果非常简单的规则 ("there is a string; it has chars; it can tell you how many chars it has") 有例外,那么 that 将被明确说明……但事实并非如此。

标准 C 函数 std::strlen 根据数组中是否存在终止零来计算字符数组的长度。 另一方面,class std::string 的对象可能嵌入了零。因此,应用于 c_str() 的函数 strlen 可能会产生与成员函数 length.

返回的值不同的结果

考虑一个简单的例子

std::string s( 10, '[=10=]' );

std::cout << s.length() << std::endl;
std::cout << std::strlen( s.c_str() ) << std::endl;

在这种情况下,第一个输出语句将输出 10,而第二个输出语句将输出 0。

此外,如果您有一个字符串,例如

std::string s( "Hello" );

然后调用成员函数resize

s.resize( 10 );

然后该函数在原始字符串后附加四个 char() 类型的值,即零。和成员函数s.length() returns 10.

标准对字符串

中的length()有这样的说法

Returns: size().

size()定义为

Returns: A count of the number of char-like objects currently in the string.

因此,如您所见,即使类字符对象的值为 '[=12=]'

,您也会获得字符串中类字符对象的数量