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

问题描述 投票:0回答:3

作为一种隐含的理解,我一直认为

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;
}

当然,没有注意到的写入操作会导致“问题”。但这不是我的问题。我想知道标准对这种行为有什么规定。

    

c++ string c-strings string-length strlen
3个回答
14
投票

str

可能包含值为

std::string
char
;当您提取 C 字符串时,除了扫描
'\0'
之外,您无法知道它有多长,这必然无法解释“二进制数据”。

这是

\0

的限制,

strlen
通过实际将此元数据记住为它知道已封装的
std::string
的计数来“修复”这一限制。

标准实际上不需要“说”任何相关内容,除了

char

给出字符串长度,无论您插入字符串中的

std::string::length
的值是多少,而且这并不禁止插入
char
。相比之下,
'\0'
的定义是告诉您到下一个
strlen
为止存在多少个
char
,这是一个根本不同的定义。

对此没有明确的措辞,因为没有必要。如果非常简单的规则有一个例外(“有一个字符串;它有

\0

;它可以告诉你它有多少个

char
”),那么
that
将被明确说明……而它不是.


4
投票
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。
    


1
投票
s.length()

有这样的说法


返回:size()。

length()

定义为


返回:字符串中当前类字符对象的数量。

因此,正如您所看到的,即使 char 类对象的值为
size()

,您也将获得字符串中 char 类对象的数量。

    

© www.soinside.com 2019 - 2024. All rights reserved.