На этом шаге мы рассмотрим различия между строками и 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(). Возвращает содержимое строки в виде массива символов. Возвращаемое значение не является действительной С-строкой,
поскольку к нему не присоединяется символ \0. - c_str(). Возвращает содержимое строки в формате С-строки (то есть с завершающим символом \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); // ОШИБКА: недействительное значение аргумента р
На следующем шаге мы рассмотрим размер и емкость строк.