Шаг 368.
Библиотека STL.
Строки. Строки и С-строки

    На этом шаге мы рассмотрим различия между строками и C-строками.

    В стандарте C++ тип строковых литералов char* был заменен типом const char*. Впрочем, для сохранения совместимости поддерживается неявное, хотя и нежелательное преобразование к типу char*. Но так как строковые литералы все же не относятся к типу string, между "новыми" объектами строкового класса и традиционными С-строками существует тесная связь: С-строки могут использоваться практически в любых операциях вместе со строками (сравнение, присоединение, вставка и т. д.). В частности, поддерживается автоматическое преобразование типа const char* в строку. С другой стороны, не поддерживается автоматическое преобразование строковых объектов в С-строки. Возможность такого преобразования была исключена по соображениям безопасности - чтобы предотвратить непреднамеренные преобразования типов, приводящие к странным последствиям (а тип char* часто ведет себя довольно странно) и неоднозначности (например, в выражении, объединяющем строку string с С-строкой, можно было бы выполнять преобразование как string в char*, так и наоборот). Вместо этого в классе string были определены специальные функции для создания или записи/копирования С-строк. В частности, функция c_str() переводит содержимое строки в формат С-строки (то есть преобразует его в символьный массив с последним символом \0). Функция сору() позволяет копировать и записывать строковые значения в существующие С-строки и символьные массивы.

    Следует помнить, что в строках не существует специальной интерпретации символа \0, который в традиционных С-строках является признаком конца строки. Символ \0 может входить в строки наравне с любым другим символом. Также учтите, что вместо параметра char* нельзя передавать NULL-указатель - это приводит к странным последствиям. Дело в том, что NULL относится к целочисленному типу и в перегруженных операциях интерпретируется как число 0 или символ со значением 0.

    Преобразование содержимого строки в массив символов или С-строку осуществляется тремя функциями.

    Функции data() и c_str() возвращают массив, принадлежащий строке, поэтому вызывающая сторона не должна модифицировать или освобождать память. Пример:

std::string s('12345");
atoi(s.c_str());         // Преобразование строки в целое число 
f(s.data(),s.length());  // Вызов функции для символьного массива
                         // и количества символов 
char buffer[100];
s.copy(buffer,100);   // Копировать не более 100 символов s в buffer 
s.copy(buffer,100,2); // Копировать не более 100 символов s в buffer,
                      // начиная с третьего символа s

    Обычно в программе следует работать со строками, а их преобразование в С-строки или символьные массивы должно производиться непосредственно перед тем, как вам потребуется содержимое строки в виде типа char*. Помните, что возвращаемые значения функций c_str() и data() остаются действительными только до следующего вызова неконстантной функции для той же строки:

std::string s;
.   .   .   .
foo(s.c_str()); // Peзультат c_str() остается действительным
                // на время выполнения команды 
const char* p;
р = s.c_str();  // p ссылается на содержимое s в формате С-строки
foo(p);	        // OK (значение р остается действительным)
s += "ext";     // Значение р становится недействительным
foo(p);         // ОШИБКА: недействительное значение аргумента р

    На следующем шаге мы рассмотрим размер и емкость строк.




Предыдущий шаг Содержание Следующий шаг