3 Вопрос: Строка инициализации и печати

вопрос создан в Thu, May 2, 2019 12:00 AM

Таблица 3.1 в статье 3.2.1 в Учебник по C ++, пятое издание гласит:

  

string s3("value") - > s3 является копией строкового литерала, а не   включая ноль.

Моя интерпретация этого такова: когда мы инициализируем строку, такую ​​как string s1("value");, переменная s1 содержит копию строки value без символа NUL в конце.

#include <iostream>

using std::cin;
using std::string;
using std::cout;
using std::endl;

int main(void)
{
        string s1("value");

        cout << s1 << endl;   // prints - value
}

Итак, эта программа вызывает UB, так как s1 не имеет терминатора NUL, и мы печатаем строку?

Я спрашиваю об этом, потому что в C попытка напечатать c-строку без терминатора NUL приводит к UB. Не обязательно ли для строк в C ++ заканчиваться на NUL?

Что мне здесь не хватает?

    
1
  1. "Не обязательно ли для строк в C ++ заканчиваться NUL?" Это верно. std::string не похож на строки в стиле C, ему не нужны нулевые терминаторы. Вы даже можете иметь NUL в строках.
    2019-05-02 14: 52: 46Z
  2. Но учтите, что если вы хотите назначить c-строку для std::string, используя единственный указатель на нее, c-string делает нужно иметь нулевой терминатор. В противном случае это не c-строка. Но std::string не требуется для его хранения.
    2019-05-02 14: 53: 45Z
3 ответа                              3                         
  

Не обязательно ли для строк в C ++ заканчиваться NUL?

Зависит от того, что вы подразумеваете под «строками». std::string не заканчиваются нулевым символом, потому что длина известна /сохранена. Строки в стиле C (иначе говоря, массивы char*), возвращаемые std::string::c_str(), должны заканчиваться нулевым символом, поскольку длина неизвестна /не сохранена.

    
3
2019-05-02 14: 55: 01Z
  

Итак, эта программа вызывает UB, поскольку s1 не имеет терминатора NUL и мы печатаем строку?

Нет. std::string обеспечивает перегрузку operator <<, которая "делает правильные вещи". Вам не нужно беспокоиться об этом.

  

Я спрашиваю об этом, потому что попытка напечатать c-строку без терминатора NUL приводит к UB. Не обязательно ли для строк в C ++ заканчиваться NUL?

Это будет зависеть от того, какая версия стандарта, которую вы используете, C ++ 98/03 не требует, чтобы в конце строки был нулевой терминатор, но c_str в основном заставляет вас делать это. C ++ 11 и выше, тем не менее, гарантируют наличие нулевого терминатора в конце строковых данных.

Обратите внимание, что завершающий нулевой символ по-прежнему не нужен, поскольку std::string из operator << может выглядеть

for (size_t i = 0; i < member_variable_size; ++i)
    std::cout << member_variable_data[i]

так что он будет работать независимо от того, был ли он один или нет. Фактически, это в значительной степени должно быть сделано, поскольку std::string может иметь встроенные нули, и он будет правильно печатать строки, например, как

int main() 
{
    std::string foo("h\0ell\0o", 7);
    std::cout << foo;
}

печатает р>

hello
    
2
2019-05-02 15: 02: 25Z
  

Что мне здесь не хватает?

Эта перегрузка оператора , которая принимает 06003509911110010103505062 в качестве второго аргумента , Так что std::string не принt-строка без нулевого терминатора, вы вызываете функцию std::cout << s1 и передаете ей operator <<.

  

Итак, эта программа вызывает UB, так как s1 не имеет терминатора NUL и мы печатаем строку?

В общем, вы можете положиться на компетенцию разработчиков, лежащих в основе используемой стандартной библиотеки, то есть мне кажется безопасным использовать этот перегруженный оператор:)

    
1
2019-05-02 14: 56: 37Z
s1
источник размещен Вот