Why is it that you can insert a '\0' char in a std::basic_string and the .length() method is unaffected but if you call char_traits<char>::length(str.c_str())
you get the length of the string up until the first '\0' character?
e.g.
string str("abcdefgh");
cout << str.length(); // 8
str[4] = '\0';
cout << str.length(); // 8
cout << char_traits<char>::length(str.c_str()); // 4
Great question!
The reason is that a C-style string is defined as a sequence of bytes that ends with a null byte. When you use .c_str()
to get a C-style string out of a C++ std::string
, then you're getting back the sequence the C++ string stores with a null byte after it. When you pass this into strlen
, it will scan across the bytes until it hits a null byte, then report how many characters it found before that. If the string
contains a null byte, then strlen
will report a value that's smaller than the whole length of the string, since it will stop before hitting the real end of the string.
An important detail is that strlen
and char_traits<char>::length
are NOT the same function. However, the C++ ISO spec for char_traits<charT>::length
(§21.1.1) says that char_traits<charT>::length(s)
returns the smallest i
such that char_traits<charT>::eq(s[i], charT())
is true. For char_traits<char>
, the eq
function just returns if the two characters are equal by doing a ==
comparison, and constructing a character by writing char()
produces a null byte, and so this is equal to saying "where is the first null byte in the string?" It's essentially how strlen
works, though the two are technically different functions.
A C++ std::string
, however, it a more general notion of "an arbitrary sequence of characters." The particulars of its implementation are hidden from the outside world, though it's probably represented either by a start and stop pointer or by a pointer and a length. Because this representation does not depend on what characters are being stored, asking the std::string
for its length tells you how many characters are there, regardless of what those characters actually are.
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With