Программирование >>  Инициализация объектов класса, структура 

1 ... 28 29 30 [ 31 ] 32 33 34 ... 395


st = st - len;

Можно попробовать исправить эту ошибку:

cout << len << : << st;

Теперь наша программа выдает что-то осмысленное, но не до конца. Ответ выглядит так:

18: ена бутылки вина

Мы забыли учесть, что заключительный нулевой символ не был включен в подсчитанную длину. st должен быть смещен на длину строки плюс 1. Вот, наконец, правильный оператор:

st = st - len - 1; а вот и и правильный результат:

18: Цена бутылки вина

Однако нельзя сказать, что наша программа выглядит элегантно. Оператор

st = st - len - 1;

добавлен для того, чтобы исправить ошибку, допущенную на раннем этапе проектирования программы, - непосредственное увеличение указателя st. Этот оператор не вписывается в логику программы, и код теперь трудно понять. Исправления такого рода часто называют заплатками - нечто, призванное заткнуть дыру в существующей программе. Гораздо лучшим решением было бы пересмотреть логику. Одним из

Во второй версии программы эта погрешность устранена. Программа успешно

#include <iostream>

заканчивается, однако полученный результат неправилен. Где мы не правы на этот раз?

const char *st = Цена бут1лки вина\n ;

int main() {

int len = 0; while ( *st++ ) ++len;

cout << len << : << st << endl;

return 0;

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



3.4.2. Класс string

Как мы только что видели, применение встроенного строкового типа чревато ошибками и не очень удобно из-за того, что он реализован на слишком низком уровне. Поэтому достаточно распространена разработка собственного класса или классов для представления строкового типа - чуть ли не каждая компания, отдел или индивидуальный проект имели свою собственную реализацию строки. Да что говорить, в нред1дущих двух изданиях этой книги м1 делали то же самое! Это порождало проблема: совместимости и переносимости программ. Реализация стандартного класса string стандартной библиотекой С++ призвана была положить конец этому изобретению велосипедов.

Попробуем специфицировать минимальный набор операций, которыми должен обладать класс string:

инициализация массивом символов (строкой встроенного тина) или другим объектом тина string. Встроенный тин не обладает второй возможностью;

копирование одной строки в другую. Для встроенного типа приходится использовать функцию strcpy();

доступ к отдельным символам строки для чтения и записи. Во встроенном массиве для этого применяется операция взятия индекса или косвенная адресация;

сравнение двух строк на равенство. Для встроенного типа используется функция strcmp() ;

конкатенация двух строк, получая результат либо как третью строку, либо вместо одной из исходных. Для встроенного типа применяется функция strcat() , однако чтобы получить результат в новой строке, необходимо последовательно задействовать функции strcpy() и strcat() ;

вычисление длины строки. Узнать длину строки встроенного типа можно с помощью функции strlen() ;

возможность узнать, пуста ли строка. У встроенных строк для этой цели

char str = 0; ...

if ( ! str ! *str )

приходится проверять два условия:

return;

вариантов в нашем случае может быть определение второго указателя, инициализированного значением st:

const char *p = st;

Теперь p можно использовать в цикле вычисления длины, оставив значение st неизменным:

while ( *p++ )



#include <string>

инициализированной строкой символов:

string st( Цена бут1лки вина\n ) ;

Длину строки возвращает функция-член size() (длина не включает завершающий

cout << Длина

<< st

<< : << st.size()

<< символов, вкчая символ новой строки\п ;

нулевой символ).

Вторая форма определения строки задает пустую строку:

string st2; пустая строка

Как мы узнаем, пуста ли строка? Конечно, можно сравнить ее длину с 0:

if ( ! st.size() )

правильно: пустая

Однако есть и специальный метод empty() , возвращающий true для пустой строки и false для непустой:

if ( st.empty() )

правильно: пустая

Третья форма конструктора инициализирует объект типа string другим объектом того же типа:

string st3 ( st );

Строка st3 инициализируется строкой st. Как мы можем убедиться, что эти строки совпадают? Воспользуемся оператором сравнения (==):

if ( st == st3 )

инициализация сработала

Класс string стандартной библиотеки С++ реализует все перечисленные операции (и гораздо больше, как мы увидим в главе 6). В данном разделе мы научимся пользоваться основными операциями этого класса.

Для того чтобы использовать объекты класса string, необходимо включить соответствующий заголовочный файл:

#include <string>

Вот пример строки из предыдущего раздела, представленной объектом типа string и



1 ... 28 29 30 [ 31 ] 32 33 34 ... 395

© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика