Концы std :: strings заканчиваются на ‘\ 0’ при инициализации строковым литералом?

Я знаю, что строковые объекты не заканчиваются нулем, но почему это должно работать?

std::string S("Hey");
for(int i = 0; S[i] != '\0'; ++i)
std::cout << S[i];

Таким образом, конструктор также копирует нулевой терминатор, но не увеличивает длину? Почему это беспокоит?

4

Решение

Таким образом, конструктор также копирует нулевой терминатор, но не увеличивает длину?

Как вы знаете, что std::string не содержит нулевой символ (и здесь не копируется нулевой символ).

Дело в том, что вы используете std::basic_string::operator[], Согласно C ++ 11, станд :: basic_string :: Оператор [] вернет нулевой символ, когда указанный индекс эквивалентен size(),

Если pos == size(), ссылка на символ со значением CharT() (нулевой символ) возвращается.

Для первой (неконстантной) версии поведение не определено, если этот символ изменен на любое значение, кроме charT(),

6

Другие решения

std::string хранит свои данные внутри себя в виде C-строки с нулевым символом в конце, но при обычном использовании не позволяет получить доступ к нулевому терминатору.

Например, если я назначу значение «Hello, World!» для строки внутренний буфер будет выглядеть так:

std::string myString("Hello, World!");

// Internal Buffer...
// [ H | e | l | l | o | , |   | W | o | r | d | ! | \0 ]
//                                                   ^ Null terminator.

В этом примере нулевой терминатор НЕ был скопирован с конца строкового литерала, но добавлен внутри std::string,

Как @songyuanyao упоминает в своем ответе, результатом этого является то, что myString[myString.size()]; возвращается '\0',

Так почему же std::string назначить нулевой терминатор в конце строки? Это, конечно, не должно поддерживать один, потому что вы можете добавить '\0' в строку, и она включена в строку:

std::string myString;
myString.size();              // 0
myString.push_back('\0');
myString.size();              // 1

Причиной такого поведения является поддержка std::string::c_str() функция. c_str() функция требуется для возврата с нулевым символом в конце const char *, Самый эффективный способ сделать это — просто вернуть указатель на внутренний буфер, но для этого внутренний буфер должен содержать нулевой символ-терминатор в конце строки. Начиная с C ++ 11, строки требуется включить нулевой терминатор для поддержки этого.

Постскриптум Хотя это и не является частью вашего вопроса, следует отметить, что цикл из вашего вопроса может НЕ возвращать полную строку, если ваша строка содержит нулевые символы:

std::string S("Hey");
S.push_back('\0');
S.append("Jude");

for(int i = 0; S[i] != '\0'; ++i)
std::cout << S[i];

// Only "Hey" is printed!
4

По вопросам рекламы [email protected]