Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Ход работы. Основные сведения о строках в языке С++.В C++ есть два вида строк: С-строки и класс стандартной библиотеки C++ string






Основные сведения о строках в языке С++. В C++ есть два вида строк: С-строки и класс стандартной библиотеки C++ string. С-строка представляет собой массив символов, завершающийся символом с ко­дом О. Класс string более безопасен в использовании, чем С-строки, но и более ресурсоемок.

Описание строк. Память под строки, как и под другие массивы, может выделяться как компилятором, так и непосредственно в программе. Длина динамической строки может задавать­ся выражением, длина нединамической строки должна быть только константным выражением. Чаще всего длина строки задается частным случаем константного выражения - константой. Удобно задавать длину с помощью именованной кон­станты, поскольку такой вариант, во-первых, лучше читается, а во-вторых, при возможном изменении длины строки потребуется изменить программу только в одном месте:

 

const int len_str = 80;

char str [len_str];

 

При задании длины необходимо учитывать завершающий нуль-символ. Напри­мер, в строке, приведенной выше, можно хранить не 80 символов, а только 79. Стро­ки можно при описании инициализировать строковыми константами, при этом нуль-символ в позиции, следующей за последним заданным символом, формиру­ется автоматически:

 

char a[100] = " Never trouble trouble";

 

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

 

char а[] = " Never trouble trouble"; // 22 символа

 

Для размещения строки в динамической памяти надо описать указатель на char, а за­тем выделить память с помощью new или mall ос (первый способ предпочтительнее):

 

char *p = new char [m];

char *q - (char *)malloc(m * sizeof(cnar));

 

Естественно, что в этом случае длина строки может быть переменной и задаваться на этапе выполнения программы. Динамические строки, как и другие динамиче­ские массивы, нельзя инициализировать при создании. Оператор

 

char *str = " Never trouble trouble"

 

создает не строковую переменную, а указатель на строковую константу, изменить которую невозможно.

Ввод-вывод строк. Для ввода-вывода строк используются как уже известные нам объекты cin и cout, так и функции, унаследованные из библиотеки С. Рассмотрим сначала первый способ:

 

#include< iostream.h>

int main()

{

const int n = 80;

char s[n];

cin> > s;

cout < < s < < endl;

return 0;

}

 

Строка вводится точно так же, как и переменные известных нам типов. Если запустите про­грамму и ввести строку из нескольких слов, выводится только первое слово. Это связано с тем, что ввод выполняется до первого пробельно­го символа (то есть пробела, знака табуляции или символа перевода строки '\n').

Можно ввести слова входной строки в отдельные строковые переменные:

 

#include < iostream.h>

int main()

{

const int n = 80;

char s[n], t[n], r[n];

cin > > s > > t > > r;

cout < < s < < endl < < < t < < endl < < r < < endl;

return 0;

}

 

Если требуется ввести строку, состоящую из нескольких слов, в одну строковую переменную, используются методы getline или get класса istream, объектом кото­рого является cin. Синтаксис вызова метода - после имени объекта ставится точка, а затем пишется имя метода:

 

#include< iostream.h>

int main()

{

const int n = 80;

char s[n];

cin.getline(s. n); cout < < s < < endl;

cin.get(s. n); cout < < s < < endl;

return 0;

}

 

Метод getl 1 пе считывает из входного потока п - 1 символов или менее (если сим­вол перевода строки встретится раньше) и записывает их в строковую перемен­ную s. Символ перевода строки также считывается (удаляется) из входного потока, но не записывается в строковую переменную, вместо него размещается заверша­ющий 0. Если в строке исходных данных более n-1 символов, следующий ввод будет выполняться из той же строки, начиная с первого несчитанного символа.

Метод get работает аналогично, но оставляет в потоке символ перевода строки. В строковую переменную добавляется завершающий 0.

Никогда не обращайтесь к разновидности метода get с двумя аргументами два раза подряд, не удалив \n из входного потока. Например:

 

cin.get(s. n); //1-считывание строки

cout < < s < < endl; //2-вывод строки

cin.get(s. n); //3-считывание строки

cout < < s < < endl; //4-вывод строки

cin.get(s. n); //5-считывание строки

cout < < s < < endl; //6-вывод строки

cout < < " Конец-делу венец" < < endl; //7

 

При выполнении этого фрагмента вы увидите на экране первую строку, выведен­ную оператором 2, а затем завершающее сообщение, выведенное оператором 7. Какие бы прекрасные строки вы ни ввели с клавиатуры в надежде, что они будут прочитаны операторами 3 и 5, метод get в данном случае «уткнется» в символ \n, оставленный во входном потоке от первого вызова этого метода (оператор 1). В ре­зультате будут считаны и, соответственно, выведены на экран пустые строки (стро­ки, содержащие 0 символов). А символ \n так и останется «торчать» во входном потоке. Возможное решение этой проблемы - удалить символ \n из входного по­тока путем вызова метода get без параметров, то есть после операторов 1 и 3 нужно вставить вызов cin. get ().

Однако есть и более простое решение - использовать в таких случаях метод getline, который после прочтения строки не оставляет во входном потоке сим­вол \n.

Если в программе требуется ввести несколько строк, метод getline удобно исполь­зовать в заголовке цикла, например:

 

#include< iostream.h>

int main()

{

const int n = 80;

char s[n];

while(cin.getline(s. n))

{

cout < < s < < endl;

- // обработка строки

}

return 0;

}

 

Рассмотрим теперь способы ввода-вывода строк, перекочевавшие в C++ из языка С. Во-первых, можно использовать для ввода строки известную нам функцию scanf, а для вывода - printf, задав спецификацию формата %s:

#include< stdio.h>

int main()

{

const int n = 10;

char s[n];

scan (" %s", s);

printf(" %s", s);

return 0;

}

 

Имя строки, как и любого массива, является указателем на его начало, поэтому использовавшаяся в предыдущих примерах применения функции scanf операция взятия адреса (&) опущена. Ввод будет выполняться так же, как и для классов ввода-вывода - до первого пробельного символа. Чтобы ввести строку, состоящую из нескольких слов, используется спецификация %s (символы) с указанием мак­симального количества вводимых символов, например:

 

scanf(" %10s", s);

 

Количество символов может быть только целой константой. При выводе можно задать перед спецификацией & количество позиций, отводимых под строку:

 

printf (" %15s". s);

 

Строка при этом выравнивается по правому краю отведенного поля. Если задан­ное количество позиций недостаточно для размещения строки, оно игнорируется, и строка выводится целиком.

Библиотека содержит также функции, специально предназначенные для ввода-вывода строк: gets и puts. Предыдущий пример с использованием этих функций выглядит так:

 

#include < stdio.h>

int main()

{

const int n = 10;

char s[n];

gets(s);

puts(s);

return 0;

}

 

Функция gets (s) читает символы с клавиатуры до появления символа новой стро­ки и помещает их в строку s (сам символ новой строки в строку не включается, вместо него в строку заносится нуль-символ). Функция возвращает указатель на строку s, а в случае возникновения ошибки или конца файла - NULL.

Функция puts (s) выводит строку s на стандартное устройство вывода, заменяя за­вершающий 0 символом новой строки. Возвращает неотрицательное значение при успехе или EOF при ошибке.

Функциями семейства printf удобнее пользоваться в том случае, если в одном опе­раторе требуется ввести или вывести данные различных типов. Если же работа выполняется только со строками, проще применять специальные функции для ввода-вывода строк gets и puts.

Операции со строками. Для строк не определена операция присваивания, поскольку строка является не основным типом данных, а массивом. Присваивание выполняется с помощью функ­ций стандартной библиотеки или посимвольно «вручную» (что менее предпочти­тельно, так как чревато ошибками). Например, чтобы присвоить строке р строку а, можно воспользоваться функциями strcpy или strncpy:

 

char a[100] = " Never trouble trouble";

char *p = new char[m];

strcry (p, a);

strcry (p, a, strlen(a) + 1);

 

Для использования этих функций к программе следует подключить заголовочный файл < string. h>.

Функция strcpy (р. а) копирует все символы строки, указанной вторым парамет­ром (а), включая завершающий 0, в строку, указанную первым параметром (р).

Функция strncpy (p, а. n) выполняет то же самое, но не более n символов, то есть числа символов, указанного третьим параметром. Если нуль-символ в исходной строке встретится раньше, копирование прекращается, а оставшиеся до n символы строки р заполняются нуль-символами. В противном случае (если n меньше или равно длине строки а) завершающий нуль-символ в р не добавляется.

Обе эти функции возвращают указатель на результирующую строку. Если обла­сти памяти, занимаемые строкой-назначением и строкой-источником, перекрыва­ются, поведение программы не определено.

Функция strlen(a) возвращает фактическую длину строки а, не включая нуль-символ.

Программист должен сам заботиться о том, чтобы в строке-приемнике хватило места для строки-источника (в данном случае при выделении памяти значение переменной m должно быть больше или равно 100), и о том, чтобы строка всегда имела завершающий нуль-символ.

Выход за границы строки и отсутствие нуль-символа являются распространенными причинами ошибок в программах обработки строк.

Для преобразования строки в целое число используется функция atoi(stг). Функ­ция преобразует строку, содержащую символьное представление целого числа, в соответствующее целое число. Признаком конца числа служит первый символ, который не может быть интерпретирован как принадлежащий числу. Если преоб­разование не удалось, возвращает 0.

Аналогичные функции преобразования строки в длинное целое число (long) и в вещественное число с двойной точностью (double) называются atoi и atof соответ­ственно.

Пример применения функций преобразования:

 

char a[ ] = " 10) Рост-162см, вес-59.5кг";

int num;

long height;

double weight;

num = atoi(a);

height = atol(& a[11]);

weight = atof(& a[25]);

cout < < num < < '' < < height < < ''< < weight;

 

Библиотека предоставляет также различные функции для сравнения строк и под­строк, объединения строк, поиска в строке символа и подстроки и выделения из строки лексем.

Работа с символами. Для хранения отдельных символов используются переменные типа char. Их ввод-вывод также может выполняться как с помощью классов ввода-вывода, так и с помощью функций библиотеки.

При использовании классов ввод-вывод осуществляется как с помощью операций помещения в поток «и извлечения из потока », так и методов get() и get (char). Ниже приведен пример применения операций:

 

#include < iostream.h>

int main()

{

char c, d, e;

cin > > c;

cin > > d > > e;

cout < < c < < d < < e < < endl;

return 0;

}

 

Вводимые символы могут разделяться или не разделяться пробельными символа­ми, поэтому таким способом ввести символ пробела нельзя. Для ввода любого сим­вола, включая пробельные, можно воспользоваться методами get() или get (с):

 

#include < iostream.h>

int main()

{

char c, d, e;

c = cin.get(); cin.get(d); cin.get(e);

cout < < c < < d < < e < < endl;

return 0;

}

 

Метод get () возвращает код извлеченного из потока символа, а метод get (с) записывает извлеченный символ в переменную, переданную ему в качестве аргумента, и возвращает ссылку на поток.

В заголовочном файле < stdiо. h> определена функция getchar() для ввода символов со стандартного ввода, а также putchar() для вывода:

 

#include < iostream.h>

int main()

{

char c, d;

c = getchar();

putchar(c);

d = getchar();

putchar(d);

return 0;

}

 

В библиотеке также определен целый ряд функций, проверяющих принадлежность символа какому-либо множеству, например множеству букв (isalfa), разделите­лей (isspace), знаков пунктуации (ispunct), цифр (isdigit) и т. д.


Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.021 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал