Почему .c_str () не добавляет '\ 0' в конце строки? - PullRequest
3 голосов
/ 06 марта 2019

При запуске этого кода я получаю "Hello Worldaaa", но в соответствии с заданием функции .c_str(), string a должно быть "Hello World\0", а string b должно быть "Hello World\0aaa", поэтому "aaa" не должно отображаться на выходе.

#include <bits/stdc++.h>

using namespace std; 

int main()
{
    string a = "Hello World";
    a = a.c_str();
    string b = a + string("aaa");

    cout << b;

    return 0;
}

Ответы [ 3 ]

4 голосов
/ 06 марта 2019

Да, вы правы в отношении станд :: строка :: c_str .

В самом деле,

Возвращает указатель на массив символов с нулем в конце с данными, эквивалентными тем, которые хранятся в строке.

Однако есть несколько соображений, которые, вероятно, вводят вас в заблуждение.


Прежде всего, утверждение:

a = a.c_str();

семантически a бездействие . Вы получаете const char* (т.е. "Hello World\0") и назначаете его на a. Однако a - это std::string, это класс, разработанный для абстрагирования «строкового типа» в C ++. Он обрабатывает автоматически '\0', прозрачно. Пользователь не должен заботиться об управлении им 1 .

Трюк внутри std::string::operator=(const char*).

Заменяет содержимое на символьную строку с нулевым символом в конце, на которую указывает s , как будто с помощью assign (s, Traits :: length (s)) .


Последний пункт, о конкатенации строк .

a + string("aaa");

Как и ранее, в этом случае оператор std::string::operator+ будет обрабатывать '\0'.

Короче, он ведет себя как:

"Hello World\0" + "aaa\0"  ===> "Hello Worldaaa\0"

Он позаботится о том, чтобы "inner '\0'" возвращал соответствующую строку с нулевым символом в конце.


1 Если он / она не играет с внутренней памятью.

1 голос
/ 06 марта 2019

Это было бы не интуитивно понятно. Помните, что завершающий нулевой символ не был явно использован пользователем. Синтаксис языка добавил его.

Это создаст много путаницы, если результат "abcd" + "xyz" окажется "abcd\0xyz" вместо интуитивного результата - "abcdxyz".

В C и C ++ конкатенация двух строк подразумевает игнорирование завершающего нулевого символа первой строки в результирующей строке. Взгляните на документацию strcat. Это явный вопрос о нулевом символе, в то время как документация std::string::operator+ - нет.

0 голосов
/ 06 марта 2019

Не совсем ...

Давайте посмотрим на эту строку:

a = a.c_str();

У вас есть std::string, которому вы пытаетесь присвоить const char*. Поэтому вы будете использовать перегрузку (3) из std::string оператора присваивания . Но это волшебным образом не меняет тип a. Другими словами, у нас все еще есть std::string!

Так что эта строка вообще не изменяет значение a.

Затем вы используете operator+, чтобы сложить два std::string. Это приведет к другому std::string, который является первым с добавлением второго, что именно то, что у вас есть!

Мне не ясно, чего вы пытаетесь достичь здесь, но если вы создали c-строку с этими значениями:

const char cstr[] = "Hello World\0aaa";

И попытавшись распечатать его, вы увидите именно то, что ожидаете.

...