STL basic_string长度为空字符

Mat*_*ith 8 c++ string stl stdstring

为什么你可以在std :: basic_string中插入一个'\ 0'字符,而.length()方法不受影响,但如果你调用,char_traits<char>::length(str.c_str())你可以获得字符串的长度直到第一个'\ 0'字符?

例如

string str("abcdefgh");
cout << str.length(); // 8
str[4] = '\0';
cout << str.length(); // 8
cout << char_traits<char>::length(str.c_str()); // 4
Run Code Online (Sandbox Code Playgroud)

tem*_*def 18

好问题!

原因是C样式字符串被定义为以空字节结尾的字节序列.当您使用.c_str()从C++中获取C样式的字符串时std::string,您将获得C++字符串存储的序列,其后面带有空字节.当你将其传入时strlen,它将扫描字节,直到它达到空字节,然后报告它之前找到的字符数.如果string包含空字节,那么strlen将报告一个小于字符串整个长度的值,因为它将在命中字符串的实际结束之前停止.

一个重要的细节是,strlen并且char_traits<char>::length是不一样的功能.但是,char_traits<charT>::length(第21.1.1节)的C++ ISO规范表示char_traits<charT>::length(s)返回最小的 i,这char_traits<charT>::eq(s[i], charT())是真的.因为char_traits<char>,eq如果通过==比较两个字符相等,函数只返回,并且通过写入构造字符char()产生一个空字节,所以这等于说"字符串中的第一个空字节在哪里?" 它本质上是strlen有效的,尽管两者在技术上是不同的功能.

std::string然而,在C++ 中,它是"任意字符序列"的更一般概念.其实现的细节隐藏在外部世界,尽管它可能由开始和停止指针或指针和长度表示.因为这种表示不依赖于存储的字符,所以询问std::string它的长度会告诉你有多少个字符,无论这些字符实际是什么.

希望这可以帮助!

  • @ dappawit-不是`c_str()`取出空字节而``data()`留下它们; 相反,它们都有空字节,`c_str()`保证最后有一个空字节,而`data`则没有.问题是字符串内部的那些字节是如何被用于C风格字符串实现的函数解释的. (6认同)