STL basic_string длина с нулевыми символами - PullRequest
8 голосов
/ 16 марта 2011

Почему вы можете вставить символ '\ 0' в std :: basic_string, и метод .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

1 Ответ

18 голосов
/ 16 марта 2011

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

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

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

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

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

...