好问题!
原因是 C 风格的字符串被定义为以空字节结尾的字节序列。当您使用.c_str()
从 C++ 中获取 C 风格的字符串时std::string
,您将返回 C++ 字符串存储的序列,其后有一个空字节。当你将它传递给 时strlen
,它会扫描字节直到它遇到一个空字节,然后报告它在此之前找到了多少个字符。如果string
包含一个空字节,那么strlen
将报告一个小于字符串整个长度的值,因为它会在到达字符串的真正结尾之前停止。
一个重要的细节是strlen
和char_traits<char>::length
不是同一个功能。但是,(第 21.1.1 节)的 C++ ISO 规范char_traits<charT>::length
说char_traits<charT>::length(s)
返回的是最小 i
的,这char_traits<charT>::eq(s[i], charT())
是正确的。对于char_traits<char>
,该eq
函数只是通过比较返回两个字符是否相等==
,并且通过写入构造一个字符char()
会产生一个空字节,因此这等于说“字符串中的第一个空字节在哪里?” 它本质上是如何strlen
工作的,尽管两者在技术上是不同的功能。
但是, C++std::string
是“任意字符序列”的更一般概念。它的实现细节对外界是隐藏的,尽管它可能由开始和停止指针或指针和长度表示。因为这种表示不依赖于存储的字符,所以询问std::string
它的长度会告诉你有多少字符,而不管这些字符实际上是什么。
希望这可以帮助!