Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Лекции / lect13

.doc
Скачиваний:
8
Добавлен:
20.05.2014
Размер:
68.1 Кб
Скачать

** cpp1 *** 17.5.2004

Лекция 13 Обработка строк

13.1 Основные правила для обработки строк в С++

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

используют указатели, а не индексы. Если быстродействие не учитывать, то

индексы предпочтительнее указателей из-за сложности понимания последних.

Кроме обычных массивов и строковых функций, соответствующих

процедурному программированию, в С++ для обработки строк можно применить объектно-ориентированное программирование (ООП), т.е. рассматривать строки как объекты и использовать специальные методы для работы с ними.

Понятие об ООП будет дано в следующей лекции.

Обобщим основные сведения о строках.

1. Строка – это массив символов: char s [4] ; char s [ ] = ” abc ” ;

  1. Обычно в конце строки обязателен символ конца строки ' \0' ,

который во многих случаях добавляется автоматически:

char s[4]={ ' a', ' b', ' c', ' \0 '}; char s[ ] = ” abc ” ;

  1. Индексы массива позволяют использовать каждый символ строки:

cout<<s[2];

  1. При выводе имени массива без индексов выводится весь массив:

cout<<s;

Отметим, что в отсутствие символа конца строки может появиться

много дополнительных символов справа и поэтому в этом случае

для вывода нужен цикл.

  1. Для работы со строками целесообразно использовать указатели: char *p = s;

Указатель – это переменная с адресом начала строки: p=&s .

  1. Для вывода (или ввода) строк можно использовать их имена или адреса,

т.е. указатели: cout << s; cout << p;

7. При выводе указателя на строку выводится строка, а не её адрес.

8. Указатели обеспечивают более быструю обработку строк, чем индексы:

s[2] или *(p + 2).

9. Указатель позволяет выделить память для строки динамически, т.е. при

выполнении exe-программы, а не при компиляции текста имя.cpp.

Для выделения памяти используется оператор new , cм. раздел 13.3.

  1. Функциям обработки строк соответствует заголовочный файл string.h .

Есть функции strlen, strcpy, strcat, strchr, strcmp, strncmp, strdup и т.д.

[И192, П435, Пд502]

11. Оператор cin>> вводит строку до первого пробела. При вводе строк

с пробелами можно использовать циклы, функцию gets или метод

cin.getline : gets (s); cin.getline ( s, 4);

Для функции gets нужен заголовочный файл stdio.h .

12. Для работы со строками в ООП удобно использовать класс string, которому

соответствует заголовочный файл cstring.h : # include < cstring.h >

13. Класс string имеет несколько конструкторов и несколько десятков методов,

например, length, getline, copy, append, compare, c_str и т.д. [П291, Пд532]

14. При инициализации строки класса string нужны скобки вместо знака

равенства, например, string s (“abcd”); т. к. здесь вызывается

конструктор.

15. Для класса string возможно использование некоторых операций вместо методов:

+ == != < += и т. д., например, string b = s + s; [П288].

13.2 Пример программы со строками

Рассмотрим пример с различными способами объявления и использования строк, аналогичный примеру раздела 10.1. В нем будут применены указанные выше правила.

// ******** d:\Proba\strok9.cpp 8.9.2003

#include <iostream.h>

#include <conio.h> // for getch

#include <string.h> / / for strlen

#include <cstring.h> // for class string

int main() {

char s1[3]={ 'a', 'b', 'c' }; //1

cout<< "s1= " << s1 <<endl; // здесь с мусором !!

char s2[4]= {'a', 'b', 'c', '\0'}; //2

cout<< "s2= " << s2 <<endl;

char s3[4]="abc" ; //3

cout <<"s3= " << s3 <<endl;

char s4[]="abc" ; //4

cout<<"s4= "<< s4 << endl;

//// * * * * у к а з а т е л и :

char *p5 = "abc"; //5

cout<<"p5= "<<p5<<endl;

char *p6= new char[4]; p6=p5; //6

cout<<"p6= "<<p6<<endl;

char *p7= new char[20]; p7=s4; //7

cout<<"p7= "<<p7<<endl;

cout<< " p7+2= " << (p7+2) <<endl;

cout<<" *(p7+2)= " << *(p7+2) <<endl;

cout<< " &p7= " << &p7 <<endl;

cout<< strlen(s4)<< " = strlen(s4) "<<endl;

cout<< strlen(p7) << " = strlen(p7)"<<endl;

cout<< strcat(p7, s4) <<" = strcat(p7, 4)" <<endl;

cout<< strcat(p7, p6) <<" = strcat(p7, p6)" << endl;

cout<<"s2[2]= "<< s2[2]<< " (s2+2)=" << (s2+2)<<endl;

//// * * * * * в в о д с т р о к // 8

cout<< " ? s4="; cin>>s4; cout << s4 << endl;

cout<< " ? p6="; cin>>p6; cout << p6 << endl;

cout<< " ?? s4="; cin.getline(s4, 4); cout << s4 <<endl;

//// * * * * * р а б о т а c к л а с с о м

char *p = "with_Class"; // 9

string a ( p ); // ! вместо string a=p; // 10

string b = a;

cout<< p << endl;

cout<< a << endl; cout<< b << endl;

string d ("as" ); cout << d <<endl;

cout<< a.find ( d ) << endl;

cout<< a.find ( "t" ) << endl;

cout<< a.append ( d ) << endl;

cout<< (a+b) << endl;

getch(); }

Комментарии //1 - //7 соответствуют семи способам объявления строк и их

последующим выводом. Следует обратить внимание на ошибку в выводе строки s1

в первом способе! Здесь будет выведена не только строка s1, но и все последующие

байты памяти до появления где-то символа ‘\0’ , т.е. мусор. Причина этого –

отсутствие символа конца строки в массиве s1, что исправлено в s2.

Отметим, что указатель можно изменять, но имя массива – это указатель-константа

и его изменять нельзя.

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

C комментария //8 начинается фрагмент, в котором строка вводится

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

Комментарий //9 показывает начало фрагмента, в котором строки

обрабатываются как объекты ООП.

Рассмотрим кратко функции и методы приведённой программы.

Функция strlen вычисляет длину строки s1 и в файле string.h имеет прототип

unsigned strlen ( char *s1);

Функция strcat приписывает вторую строку к первой и имеет прототип

char * strcat ( char *s1, char *s2);

Метод find возвращает позицию первого вхождения подстроки-аргумента

в исходную строку.

Метод append приписывает строку – аргумент к исходной строке.

Метод getline вводит строку или её часть, длиной не более указанного

количества символов с учетом концевого символа '\0' .

Для работы в системе Builder и для графики может быть полезна

функция sprintf, которая преобразует весь список выводимых значений в одну

строку с учетом всей информации о форме вывода. Имя строки-результата

является первым аргументом функции, а далее – всё как в функции printf:

управляющая строка и список вывода. Пример:

sprintf ( str, “ k= % i x=%5.2f \n “ , k, x ) ; (13.1)

Здесь str – это полученная строка символов, т.е. это либо символьный массив, либо указатель. Для функции sprintf нужно подключить заголовочный файл <stdio.h>

13.3 Оператор динамического выделения памяти new

Оператор new выделяет память при выполнении программы, а не при её

компиляции. Рассмотрим конкретный оператор программы

char *p6= new char[4]; (13.2)

Здесь p6 – указатель на символьный массив, причем тип массива записывается

и в левой, и в правой частях оператора. В квадратных скобках указывается

количество элементов массива, что соответствует обычным объявлениям

массивов. Вместо числа здесь могут использоваться переменные, что невозможно

в обычных объявлениях массивов, т.е. при статическом распределении памяти.

Есть и другие формы записи оператора new для простых переменных

и многомерных массивов.

Если необходимо, то выделенную для массива память можно освободить

оператором delete.

13.4 Заключение по процедурному программированию

Процесс программирования можно представить как определение данных и

последовательности вызовов функций. Программа состоит из большого количества функций, которые могут храниться в одном или нескольких файлах. В лекциях рассматриваются только программы, записываемые в один файл с расширением .cpp. Сложные программы обычно являются многофайловыми и есть некоторые особенности их построения и компиляции. Такие программы требуют специального изучения.

Отметим здесь, что термин " программный модуль" обычно относится к одному файлу,

и он соответствует независимой единице компиляции..

Программирование, которое рассматривает программу как совокупность взаимодействующих функций, называют функциональным или процедурным. Второй подход к программированию называется объектно-ориентированным (ООП) и он требует других идей при постановке задачи и разработке программы. Отличие ООП

от процедурного программирования особенно существенно в постановке задач и в алгоритмах. Данная лекция является последней по процедурному программированию

и с лекции 14 начинается ООП.

Для процедурного программирования рассмотрели два языкa программирования, а вернее 2 системы программирования, т.к. программы не только составлялись, но и выполнялись в определенной среде. В курсовой работе использовались программа MathCAD2000 ( в ДК есть также MathCAD2 для DOS) и система программирования Borland C++. Система программирования - это большой пакет программ, запускаемый пользователем, операционной системой или другими программами. Системы программирования включают трансляторы, компоновщики, интерпретаторы, большое количество стандартных подпрограмм, а также много других системных модулей. Каждая из рассмотренных систем существует и для других ОС.

При переходе к другой ОС изменяются системные подпрограммы, но правила

языка почти не меняются. Следует обратить внимание здесь на слово "почти".

Область применимости каждого из языков условно показана на рис. 13.1.

Волнистые линии обозначают зыбкие границы различных областей. Ось x

соответствует объему данных в решаемых задачах, а ось y характеризует

сложность используемых алгоритмов. Вблизи начала координат, когда данных

мало, а алгоритмы очень простые, показана штриховкой область использования

системы MathCAD. Но следует помнить, что MathCAD позволяет тестировать и

сложные вычислительные программы, составленные на любых языках.

Алгоритм Паскаль ٤ С++

Фортран ٤ Си

٤ Java, С#

~~~~~~~~~~~~~~~~~~~~~~~~~

٤

SQL, VBasic и др. для БД

٤

0 Данные

Рис. 13.1 Области применимости различных языков программирования.

Штриховкой показана область применимости системы MathCAD.

По данным опроса 1000 крупных фирм США, занимающихся разработкой

информационных систем [Computer World, 1995, п. 17], широко применяются

следующие системы программирования: Power Builder (44%), Visual Basic (42%),

Cobol (40%), Cи++ (20%), Access (18%), Oracle (14%). При опросе

допускался выбор нескольких систем. Заметим, что в настоящее время трудно

получить более новую информацию об используемых языках, т.к. фирмы

скрывают эти сведения, считая их очень важными.

Выбор конкретного языка для создания или сопровождения программ

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

Выбор за Вами!

Следующие лекции этого и следующего семестра будут посвящены ООП.

Литература

[И] Ишкова Э.А. С++ . Начала прогрраммирования. М.:2001. 350 с.

[П] Павловская Т.А. С/С++. Учебник для вузов. Питер, 2002. 460 с.

[Пд] Подбельский В.В. Язык С++. М.: 2000. 560 с.

[K] Kрупник А. Изучаем С++ . Питер, 2003. 250 с.

[Л] Либерти Д. Освой самостоятельно С++ за 21 день. 2002. 815 с.

Контрольная работа: составить программу запроса и ввода пароля.

Попытаться написать также операторы для его проверки.

5

Соседние файлы в папке Лекции