STL basic_string length с нулевыми символами

Почему вы можете вставить '\ 0' char в std:: basic_string, а метод .length() не изменяется, но если вы вызываете char_traits<char>::length(str.c_str())</char>, вы получаете длину строки до тех пор, пока первый символ '\ 0'?

например.

string str("abcdefgh");
cout << str.length(); // 8
str[4] = '\0';
cout << str.length(); // 8
cout << char_traits<char>::length(str.c_str()); // 4
</char>
1 ответ

Отличный вопрос!

Причина в том, что строка в стиле C определяется как последовательность байтов, которая заканчивается нулевым байтом. Когда вы используете .c_str() для получения строки C-стиля из С++ std::string, вы возвращаете последовательность, в которой строка С++ хранится с нулевым байтом после нее. Когда вы передадите это значение в strlen, он сканирует по байтам до тех пор, пока не ударит нулевой байт, а затем сообщит, сколько символов он нашел до этого. Если string содержит нулевой байт, то strlen будет сообщать значение, которое меньше, чем вся длина строки, так как она остановится перед ударом по реальному концу строки.

Важной деталью является то, что strlen и char_traits<char>::length</char> НЕ являются одной и той же функцией. Однако спецификация С++ ISO для char_traits<chart>::length</chart> (& sect; 21.1.1) говорит, что char_traits<chart>::length(s)</chart> возвращает наименьший i, так что char_traits<chart>::eq(s[i], charT())</chart> является истинным. Для char_traits функция eq просто возвращается, если два символа равны, выполняя сравнение ==, а построение символа путем записи char() создает нулевой байт, и поэтому это равно выражению "где первый нулевой байт в строке?" По существу, как работает strlen, хотя эти два являются технически разными функциями.

A С++ std::string, однако, это более общее понятие "произвольная последовательность символов". Детали его реализации скрыты от внешнего мира, хотя он, вероятно, представлен либо указателем начала и остановки, либо указателем и длиной. Поскольку это представление не зависит от того, какие символы хранятся, запрос std::string по его длине указывает вам, сколько символов есть, независимо от того, что эти символы на самом деле.

Надеюсь, это поможет!

licensed under cc by-sa 3.0 with attribution.