作为一种隐含的理解,我一直认为
std::string
的每个实现都必须满足每个字符串strlen(str.c_str()) == str.length()
的str
。
C++ 标准对此有何规定? (是吗?)
背景: 至少 Visual C++ 和 gcc 附带的实现不具有此属性。 考虑这个例子(参见这里的实例):
// 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
可能包含值为
std::string
的 char
;当您提取 C 字符串时,除了扫描 '\0'
之外,您无法知道它有多长,这必然无法解释“二进制数据”。这是
\0
的限制,
strlen
通过实际将此元数据记住为它知道已封装的 std::string
的计数来“修复”这一限制。标准实际上不需要“说”任何相关内容,除了
char
给出字符串长度,无论您插入字符串中的
std::string::length
的值是多少,而且这并不禁止插入 char
。相比之下,'\0'
的定义是告诉您到下一个strlen
为止存在多少个char
,这是一个根本不同的定义。对此没有明确的措辞,因为没有必要。如果非常简单的规则有一个例外(“有一个字符串;它有
\0
;它可以告诉你它有多少个
char
”),那么 that将被明确说明……而它不是.
char
根据数组中是否存在终止零来计算字符数组的长度。 另一方面,
std::strlen
类的对象可能嵌入了零。因此,应用于 c_str() 的函数 strlen 可能会产生与成员函数 length 返回的值不同的结果。考虑一个简单的例子
std::string
在这种情况下,第一个输出语句将输出 10,而第二个输出语句将输出 0。
此外,如果你有一个像这样的字符串
std::string s( 10, '\0' );
std::cout << s.length() << std::endl;
std::cout << std::strlen( s.c_str() ) << std::endl;
然后调用成员函数resize
std::string s( "Hello" );
然后该函数在原始字符串后面附加四个
s.resize( 10 );
类型的值(按零)。成员函数
char()
返回 10。s.length()
有这样的说法
返回:size()。
且
length()
定义为
返回:字符串中当前类字符对象的数量。
因此,正如您所看到的,即使 char 类对象的值为
size()
,您也将获得字符串中 char 类对象的数量。