Главная страница
Навигация по странице:

  • Класс String из библиотеки VCL.

  • Работа со строками в текстовых компонентах.

  • 3.2. Файлы и потоки

  • Поточные классы и потоки C++.

  • Открытие файла.

  • БГУ Пособие - Программирование в C++ Builder. Учебное пособие по курсу методы программирования для студентов специальностей


    Скачать 1.24 Mb.
    НазваниеУчебное пособие по курсу методы программирования для студентов специальностей
    АнкорБГУ Пособие - Программирование в C++ Builder.pdf
    Дата26.05.2018
    Размер1.24 Mb.
    Формат файлаpdf
    Имя файлаБГУ Пособие - Программирование в C++ Builder.pdf
    ТипУчебное пособие
    #19699
    страница5 из 12
    1   2   3   4   5   6   7   8   9   ...   12
    Пример.
    #include
    #include using namespace std; void main(){ string str1(“ABCDEFGH”),str2(“”),str3; char s[]=”Programming”; cout<<”length of str1: “<// Выводится length of str1: 8 cout<<”size of str1: “<// Выводится size of str1: 8 if(str1.empty()) cout<<”The string str1 is empty”<// Выводится The string str1 is not empty if(str2.empty()) cout<<”The string str2 is empty”<// Выводится The string str2 is empty str3.assign(str1);

    48
    cout<<”str3: “<// Выводится str3: ABCDEFGH str3.assign(str1,2,4); cout<<”str3: “<// Выводится str3: CDEF str3.assign(s,7); cout<<”str3: “<// Выводится str3: Program str3.append(“ming”,4); cout<<”str3: “<// Выводится str3: Programming str3.append(str1); cout<<”str3: “<// Выводится str3: ProgrammingABCDEFGH str1.append(str3,3,5); cout<<”str1: “<// Выводится str1: ABCDEFGHgramm str1.swap(str3); cout<<”str1: “<// Выводится str1: ProgrammingABCDEFGH cout<<”str3: “<// Выводится str3: ABCDEFGHgramm str1.erase(11); cout<<”str1: “<// Выводится str1: Programming str3.erase(8,5); cout<<”str3: “<// Выводится str3: ABCDEFGH str3.insert(2,str1); cout<<”str3: “<// Выводится str3: ABProgrammingCDEFGH str1.insert(10,str3,1,2); cout<<”str1: “<// Выводится str1: ProgramminBPg str1.replace(10,3,str3,5,1); cout<<”str1: “<// Выводится str1: Programming str3.replace(2,13,”CD”,2); cout<<”str3: “<// Выводится str3: ABCDEFGH str1.insert(2,str3); str1.insert(13,str3); cout<<”str1: “<// Выводится str1: PrABCDEFGHogrABCDEFGHamming string::size_type p; p=str1.find(str3); cout<<”p= “<

    49
    // Выводится p= 2 p=str1.find(str3,3); cout<<”p= “<
    // Выводится p= 13 p=str1.find(‘A’); cout<<”p= “<
    // Выводится p= 2 p=str1.find(“CDE”); cout<<”p= “<
    // Выводится p= 4 p=str1.rfind(str3); cout<<”p= “<
    // Выводится p= 13 p=str1.rfind(‘A’); cout<<”p= “<
    // Выводится p= 13 p=str1.rfind(“AB”); cout<<”p= “<
    // Выводится p= 13 str2=str3.substr(2,4); cout<<”str2: “<// Выводится str2: CDEF cout<<”C-string for str3: “<// Выводится C-string for str3: ABCDEFGH
    }
    Следующий пример также иллюстрирует применение класса string в
    C++Builder. Строка отображается в компонентах типа строки редактиро- вания Edit1 и Edit2. Процедура запускается кнопкой Button1.
    #include
    #include
    // Обработчик события, возникающего при нажатии
    // кнопки "Show" void __fastcall TForm1::ButtonlClick(TObject *Sender)
    {
    // Создание экземпляра класса string string str; str = "C++ "; str += "is the best..";
    Edit1->Text = str.c_str();// Преобразование к C-строке
    // Объявление символьного массива языка С char buff[30]; strcpy(buff, "Builder C++ "); strcat(buff, "is the best too."); int len = strlen(buff);
    Edit2->Text = buff; if (len >= 30)

    50
    ShowMessage("Переполнение буфера!!!");
    }
    Метод c_str () возвращает указатель на символьный массив, содер- жащий копию строки из объекта str. Попытка присваивания значения объекта str свойству Text объекта Edit2 выдала бы ошибку компиляции.
    Отметим, что при создании экземпляра str не пришлось указывать пре- дельный размер строки. Класс string динамически отводит дополнитель- ную память при необходимости.
    В следующем примере для выбора файла открывается диалоговое ок- но класса TOpenDialog при нажатии кнопки Button2. Имя файла отобра- жаетсяся в объекте Memo1 главной формы Form1. Имя файла затем ис- пользуется для открытия выбранного файла, ввода строки и ее вывода в объект Memo1.
    #include
    #include void __fastcall TForm1::Button2Click(TObject *Sender){ string str, str1; // Строки будут содержать путь и имя файла char buf[80]; if (OpenDialog1->Execute())
    {
    Caption = OpenDialog1->FileName; // полный путь и имя файла str = OpenDialog1->FileName.c_str();
    } str1=str; str.insert(0,"Имя файла: ") ;
    Memo1->Lines->Add(str.c_str());
    // Вывести в Memo1 путь и имя файла ifstream in(str1.c_str()); in>>buf;
    Memo1->Lines->Add(buf); // Вывести в Memo1 введенную строку
    }
    Класс String из библиотеки VCL. При работе с компонентами VCL часто встречается тип AnsiString для описания строк произвольной дли- ны. Из-за того, что название AnsiString не кажется привлекательным, пользователям C++Builder рекомендуется его синоним – класс String (на- звание начинается с заглавной буквы) Действительно, в файле sysdefs.h, который автоматически включается в заголовки разрабатываемых при- ложений, можно найти определение тождественности типов typedef AnsiString String;
    Конструкторы класса String позволяют создавать строчные объекты из переменных типа char*, int или даже double. Например:
    String str = "Текстовая строка";

    51
    Класс String имеет ряд переопределенных операторов присваивания
    (=), конкатенации (+), сравнения, характерных для строчных классов во- обще. При сравнении разнотипных объектов неявное преобразование ти- па выполняется автоматически: char* buff = "Текстовая строка";
    String str = "Текстовая строка"; if (str == buff) {…} // если строки одинаковые
    Класс String инкапсулирует набор методов, которые позволяют реа- лизовать операции над строками. Наиболее часто используются следую- щие методы: c_str() – возвращает указатель char* на С-строку, содержащую копию исходной строки.
    Length() – возвращает длину строки (число символов в строке).
    IsEmpty() – возвращает значение true, если длина строки равна нулю.
    Insert() – вставляет текст в указанную позицию строки.
    Delete() – удаляет заданное число символов из строки.
    Pos() – возвращает индекс начала заданной комбинации символов в строке.
    LastDelimiter() – возвращает индекс последнего вхождения в строку заданного символа-ограничителя.
    LowerCase() – возвращает измененную исходную строку, символы которой заменяются строчными буквами (приводятся к нижнему регист- ру).
    UpperCase() – возвращает измененную исходную строку, символы которой приводятся к верхнему регистру.
    Trim() – возвращает измененную исходную строку, в которой удале- ны управляющие символы, а также пробелы в начале и конце строки.
    Format() – форматирование строки похожее на работу функции sprintf().
    ТоInt() – преобразование строки в целое число.
    ТоDouble() – преобразование строки в число с плавающей точкой.
    SubString() – создает строку, равную некоторой подстроке исходной строки.
    Существуют два способа преобразования цифровых строк, вводимых в окна редактирования, в числа:
    String str; str = Editl->Text; int vail = atoi(str.c_str()); // с помощью функции atoi() int val2 = str.ToInt(); // с помощью метода ToInt()
    Отметим особенность класса String: символы строки индексируются начиная с 1 (как в Паскале), а не с 0 (как в C++).

    52
    Пример. Создается приложение, позволяющее выполнять сложение двух чисел.
    Будем использовать компоненты TEdit, TLabel и TButton.
    Используемые свойства и методы:
    TEdit: Name (имя объекта), ReadOnly (режим "только чтение"), Text
    (строка типа String), GetTextLen (длина строки), GetTextBuf (преобразо- вание свойства Text в С-строку).
    Используемые свойства и события компонента TButton: Caption (над- пись на кнопке), OnClick (событие, действия проводимые при нажатии на кнопку).
    Используемое свойство компонента TLabel: Caption (надпись).
    Ниже приводится обработчик события нажатия на кнопку:
    //Unit1.cpp: ------------------------------------------------------ void __fastcall TForm1::Button1Click(TObject *Sender){ int Size = Edit1->GetTextLen() + 1; char *Buffer = new char[Size];
    Edit1->GetTextBuf(Buffer,Size); for(int i = 0; i < Size-1; i++) if(!isdigit(Buffer[i])&&Buffer[i]!='.') {
    Application->MessageBox("Вводите только цифры и точку",
    "Ошибка!", MB_OK);
    Edit1 -> Text = “”; return; } double n = atof(Buffer); delete[] Buffer;
    // Выбрасывается исключение, если в Edit2 введено не число try
    { double m; m= Edit2->Text.ToDouble();
    Edit3->Text = n+m; } catch (...){
    Application->MessageBox("Ошибка при вводе второго числа",
    "Ошибка!", MB_OK);
    Edit2 -> Text = “”; return; }
    }
    На рис. 15 показана форма приложения в процессе выполнения.

    53
    Рис. 15. Результат запуска приложения
    Работа со строками в текстовых компонентах. Компонент TLabel позволяет создать надпись:
    Label1->Font->Color=clRed;
    Label1->Caption=“Это красная метка”;
    Компонент TEdit представляет собой окно для ввода/вывода строки:
    Edit2->Text=Edit1->Text;
    Компонент TMemo используется для ввода и вывода нескольких строк:
    Memo1->Lines->Strings[i];
    // доступ к i-й строке
    Свойство Lines содержит ряд методов: Add(), Append() – добавить новую строку; Delete(n) – удалить строку с номером n; SaveToFile(“имя файла”) – сохранить в файле, LoadFromFile(“имя файла”) – загрузить из файла. Например:
    Memo1->Lines->Add(Edit1->Text);
    Списки – являются производными от двух основных классов:
    TStringList – строчный список, TList – список объектов общего назначе- ния. Для отображения списков используются компоненты TListBox,
    TComboBox и другие.
    Компонент TListBox – список строк с линейной прокруткой.
    Пример.
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    TStringList *MyList=new TStringList;
    ListBoxl->Clear(); // очистить список
    ListBox1->Items->Add("Первый элемент");
    // Свойство Items содержит метод Add() и другие методы
    MyList->Add(ListBox1->Items[ListBox1->ItemIndex+1].GetText());
    MyList->Add("Последняя строка");
    ListBox1->Items->AddStrings(MyList);
    }
    Контейнерные списочные классы TStringList и TList решают пробле- му динамического распределения памяти. Хотя списочные классы
    TStringList и TList не являются прямыми потомками одного предка, од- нако они имеют много общих методов: Add() – добавить элемент в конец

    54
    списка; Clear() – очистить список; Delete() – удалить элемент с указан- ным номером; Exchange() – поменять два элемента местами; Insert() – вставить элемент в указанную позицию; Move() – переместить элемент из одной позиции в другую; Sort() – отсортировать список. Важным до- полнением к перечисленным методам является свойство Count, содер- жащее текущее число элементов в списке.
    Класс TStringList является потомком класса ТStrings, наследующим свойства и методы родителя. Однако TStrings это абстрактный базовый класс, который не способен производить объекты.
    Ниже приводится пример инициализации списка типа TStringList в конструкторе главной формы: void _fastcall TForml::TForml(TComponent* Owner) : TForm(Owner)
    { TStringList * MyList;
    MyList = new TStringList; // создать объект
    MyList->Add("Раз");
    MyList->Add("Два");
    MyList->Add("Три");
    MyList->Duplicates = dupIgnore; // игнорировать дубликаты
    MyList->Sorted = true; // сортировка списка
    ListBox1->Items->AddStrings(MyList); // отображение списка
    }
    Метод Add() добавляет в конец списка строку вместе с указателем на сопровождающий объект. Метод AddStrings() добавляет в конец списка группу строк, взятых из другого списочного объекта. Метод Find() выда- ет номер строки в отсортированном списке и возвращает значение false, если такой строки нет в списке. Метод IndexOf() возвращает номер стро- ки, под которым она впервые встретилась в списке (как отсортирован- ном, так и нет). Метод LoadFromFile() загружает строки списка из тек- стового файла. Метод SaveToFile() сохраняет список в текстовом файле
    Для хранение объектов используется другой списочный класс TList.
    Ниже приводится пример использования класса TList для хранения раз- личных объектов (модуль Unit2.cpp). Конструктор главной формы созда- ет список MyList, а затем заносит в него названия файлов, содержащих значки выполняемых программ, и сами значки.
    TList* MyList; // объявление в файле Unit2.h
    // Инициализация списка конструктором главной формы
    __fastcall TForm2::TForm2(TComponent* Owner) : TForm(Owner)
    {
    MyList = new TStringList; // создать объект MyList
    // Загрузить файл имен и отобразить их в компоненте ListBox2
    ListBox2->Items->LoadFromFile("Names.txt") ;
    // Перебрать имена программ и сформировать список MyList

    55
    for (int i=0; iItems->Count; i++)
    {
    String str = ListBox2->Items->Strings[i]; int pos=str.LastDelimiter(“.”); // найти символ ‘.’ str.Delete(pos,4); // стереть расширение файла .exe str.Insert(“.ico”,pos); // заменить расширение файла на .ico
    TIcon* icon = new TIcon; // создать новый объект icon icon->LoadFromFile(str); // загрузить объект icon
    MyList->AddObject(str, icon); // добавить str, icon в список
    }
    }
    Элементы списка нумеруются, начиная с 0, и адресуются посредст- вом индексируемого свойства Strings[i]. Например, заголовку формы можно присвоить название, взятое из второй строки списка следующим образом:
    Form1->Caption = MyList->Strings[2];
    В ряде случаев удобно интерпретировать строчный список как еди- ную строку текста. Свойство Text содержит все строки списка:
    Form1->Caption = MyList->Text;
    Далее приводится реакция на событие выбора строки из списка
    ListBox2: void__fastcall TForm2::ListBox2Click(TObject *Sender) int i = ListBox2->ItemIndex; // номер строки
    //Сдвинуть изображение и вывести пиктограмму
    Label2->Top=8+i*16; // сдвинуть изображение стрелки
    Image2->Top = i*16; // сдвинуть изображение значка
    Image2->Picture->Icon = dynamic_cast (MyList->Objects [i] ) ;
    // Свойство CommaText содержит все строки списка,
    // разделенные запятыми:
    Form1->Caption = MyList->CommaText;
    }
    Свойство CommaText преобразует список к формату SDF (System
    Data Format), обеспечивая возможность импорта данных из внешней программы непосредственно в контейнерный объект VCL. При этом лю- бая строка, содержащая пробелы или запятые, заключается в двойные кавычки.
    Листинг кодового модуля Unit2.cpp, приведенный выше, иллюстри- рует применение метода AddObject() на примере списка, в котором име- на выполняемых программ файла Names.txt ассоциируются с их пикто- граммами (объектами класса TIcon). Конструктор главной формы создает список MyList, объявленный в интерфейсном модуле Unit2.h, а затем за- носит в него названия и изображения пиктограмм. Упомянутое ранее ин-

    56
    дексируемое свойство Objects содержит типизированный указатель
    TObject*, поэтому при выборе пиктограммы оператор dynamic_cast пре- образует ее тип обратно к TIcon*.
    Наиболее характерное свойство списка TList это Capacity, которое содержит максимальную текущую емкость контейнера. Это значение не является пределом, список всегда можно при необходимости расширять и далее. Преимущества этого свойства появляются, когда списки стано- вятся слишком объемными. Дело в том, что алгоритм перераспределения памяти под списочные классы VCL начинает работать медленно при больших размерах контейнера. Если значение свойства Capacity опреде- лить заранее, сразу же после создания списка, перед добавлением в него новых элементов, то этот алгоритм вообще не включается до тех пор, по- ка заданная емкость контейнера не будет исчерпана. Если предполагает- ся хранить большое количество объектов в списке, то его емкость следу- ет определить сразу же после создания:
    TList* MyList = new TList;
    MyList->Capacity = 1000;
    MyList->Add(new TMyObject); // добавить объект
    Рассмотрим, как можно извлекать объекты из списка. Для динамиче- ского преобразования указателя типа void* обратно к типу TMyObject* (в нашем примере) можно использовать оператор dynamic_cast (MyList->Items [i]) ; или применить статическое преобразование типа в стиле языка С:
    (TMyObject*)MyList->Items[i] ;
    Класс TList предназначен для хранения данных любого типа. Адрес- ный указатель void* на объект любого типа передается как параметр та- ким методам, как Add() и Insert(). Класс TList инкапсулирует ряд специа- лизированных методов: First() – возвращает первый указатель списка
    (элемент индексируемого свойства Items[0]); Last() – возвращает послед- ний указатель списка (элемент индексируемого свойства Items[Count]);
    Expand() – увеличивает размер списка, когда его текущая емкость Count достигла значения свойства Capacity
    3.2. Файлы и потоки
    C++Builder предоставляет разработчикам несколько способов органи- зации ввода-вывода файлов:
    • в стиле языка С;
    • поточные классы стандартного C++;
    • класс TFileStream из библиотеки VCL.

    57
    Поточные классы и потоки C++. Классы ifstream и оfstream, ис- пользуемые для чтения и записи в потоки, являются производными от базового класса ios. Класс fstream способен одновременно читать и пи- сать информацию в поток. Под потоками понимают объекты поточных классов. Для использования классов необходимо включить в заголовок модуля файл fstream.h.
    Открытие файла. Потоки открываются с помощью конструктора или с помощью метода open().
    Режим открытия файлов задают флаги-члены данных перечисляемого типа класса ios: enum open_mode { арр, binary, in, out, trunc, ate };
    В табл. 2 приведены возможные значения флагов.
    Таблица 2
    Режим
    Назначение in
    Открыть для ввода (по умолчанию для ifstream) out
    Открыть для вывода (по умолчанию для ofstream) binary
    Открыть файл в бинарном режиме app
    Присоединять данные; запись в конец файла ate
    Установить указатель позиционирования на конец файла trunc
    Уничтожить содержимое, если файл существует (выбирается по умолчанию, если флаг out указан, а флаги ate и арр – нет)
    Например: ifstream file; file.open("test.dat", ios::in | ios::binary); ofstream file; file.open("test.txt", ios:out | ios::app);
    1   2   3   4   5   6   7   8   9   ...   12


    написать администратору сайта