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 char
s; it can tell you how many char
s 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=]'
。
,您也会获得字符串中类字符对象的数量
作为一种隐含的理解,我一直认为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 char
s; it can tell you how many char
s 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=]'
。