Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
LAB_TP_2013.doc
Скачиваний:
82
Добавлен:
02.06.2015
Размер:
15.36 Mб
Скачать

Лабораторная работа 2

ТЕКСТОВЫЕ ФАЙЛЫ, СИМВОЛЫ, СТРОКИ

Задание

Создать текстовый файл с расширением .dat, содержащий текст, величина которого не превышает 1000 символов, а длина строки текста содержит не более 70 символов.

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

Проектирование приложения.

Выбор, размещение и задание свойств компонентов.

Коды обработчиков событий и функций

Для подготовки текста, выводимого в файл, воспользуемся окном редактирования многострочного текста – компонентом Memo, в котором для всего текста формат одинаков. Сохранять текст в файле удобно, используя компонент “Сохранить файл” –SaveDialog, а для чтения из файла – компонент “Открыть файл” –OpenDialog.

Выводить текст, имея в виду последующую работу с текстом, целесообразно в многострочное окно редактирования – компонент RichEdit, который работает с текстом в обогащенном форматеRTF. Здесь можно устанавливать атрибуты выделенного текста свойствомSelAttributes, которое имеет ряд подсвойств, например,Style(стиль). Весь текст вRichEdit, представленный одной строкой типаAnsiString, внутри которой используются разделители типа символов возврата каретки и перевода строки, содержится в свойствеText.

MemoиRichEdit имеют общее основное свойство –Lines, содержащее текст окна в виде списка строк. Доступ к отдельной строке текста, например первой, можно получить так:RichEdit1->Lines->String[0].Во время выполнения приложения можно заносить текст в окно с помощью методов свойстваLines.

При работе с MemoиRichEditпользуются компонентомPopupMenu– контекстным всплывающим меню. Это меню привязано к конкретным компонентам. Оно всплывает, если во время, когда данный компонент (в нашем случаеMemoилиRichEdit) находится в фокусе, пользователь щелкнет правой кнопкой мыши. ДляMemoвсплывающее меню должно содержать командыСохранитьиСохранить как, а дляRichEditОткрыть.

Первое и второе слова, которые нужно найти и выделить в окне RichEdit, а затем там же поменять их местами, удобно задавать в однострочных окнах редактирования с метками –LabeledEdit. Введенный в окно текст присваивается свойствуText, который имеет тип строкиAnsiString.

В компонентах Memo,RichEditиLabeledEditсвойства только времени выполненияSelLength,SelStart,SelTextопределяют соответственно длину выделенного текста, позицию перед первым символом выделенного текста и сам выделенный текст.

  1. Запустите C++Builder 6.

  1. Создайте новый проект командой Файл/Новый/Приложение.

  2. Сохраните файлы модуля и проекта командой Файл/Сохранить все под именами LR_2 и PR_LR_2 в каталоге ТЕХН_ПРОГР. Для этого удобно использовать соответствующую быструю кнопку (Сохранить все). В последующих сеансах работы сохраненный проект можно открыть командой Файл/Открыть проект (или Повторно открыть). Теперь перейдем к проектированию приложения - переносам на форму необходимых компонентов и заданию их свойствам значений, а в обработчиках событий – размещению кодов соответствующих алгоритмов. (Рекомендуется нажимать кнопку Сохранить все по окончании работы с каждым компонентом.) В результате проектирования получим форму, представленную на рис.2.1.

Рис.2.1 – форма по окончании проектирования

  1. Выделите форму, щелкнув на ней левой кнопкой мыши, и в свойство Caption(надпись) впишите ТЕКСТОВЫЕ ФАЙЛЫ, СИМВОЛЫ, СТРОКИ.

  2. Перенесите на форму (страница Диалоги) компоненты SaveDialog1 и OpenDialog1. Все диалоги являются невизуальными компонентами, так что место их размещения на форме не имеет значения. При обращении к этим компонентам вызываются стандартные диалоги.

  3. Перенесите дважды на форму со страницы Стандарт компонент PopupMenu. Он также является невизуальным компонентом. Двойным щелчком на компоненте PopupMenu1 перейдите в Конструктор Меню (окно Form1->PopupMenu1) и внесите разделы Сохранить и Сохранить как, а для компонента PopupMenu2- Открыть.

  4. Перенесите на форму компоненты Memo1 (страница Стандарт) и RichEdit1 (страница Win32). В свойство PopupMenu компонента Memo1 внесите из выпадающего списка PopupMenu1, а в свойство PopupMenu компонента RichEdit1 - внесите PopupMenu2.

  5. В файле LR_2.cpp перед обработчиком щелчка на разделе Сохранить дайте объявление

AnsiString MyFName="";

а в обработчик щелчка на разделе Сохранить внесите (курсив)

void __fastcall TForm1::N1Click(TObject *Sender)

{

if(MyFName!="")

Memo1->Lines->SaveToFile(MyFName);

else

if(SaveDialog1->Execute())

{

MyFName=SaveDialog1->FileName;

Memo1->Lines->SaveToFile(SaveDialog1->FileName);

}

}

  1. В обработчик щелчка на разделе Сохранить как внесите (курсив)

void __fastcall TForm1::N2Click(TObject *Sender)

{

SaveDialog1->FileName=MyFName;

if(SaveDialog1->Execute())

{

MyFName=SaveDialog1->FileName;

Memo1->Lines->SaveToFile(SaveDialog1->FileName);

}

}

  1. В обработчик щелчка на разделе Открыть внесите (курсив)

void __fastcall TForm1::N3Click(TObject *Sender)

{

if(OpenDialog1->Execute())

{

MyFName=OpenDialog1->FileName;

RichEdit1->Lines->LoadFromFile(OpenDialog1->FileName);

}

}

  1. Перенесите на форму (рис.2.1) кнопку Button1 (страница Стандарт) с надписью СБРОС для очистки окон редактирования; перед обработчиком щелчка на кнопке внесите int f=0; а в обработчик – {курсив}

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Memo1->Clear();RichEdit1->Clear();

LabeledEdit1->Clear(); LabeledEdit2->Clear();

Memo1->SetFocus();

f=1;

}

  1. Поместите на форме, ниже кнопки с надписью СБРОС, окно редактирования с меткой LabeledEdit1 (страница Дополнительно). Свойству LabelPosition присвойте значение lpAbove (из выпадающего списка), а раскрыв свойство EditLabel, в подсвойство Caption впишите первое слово.

  2. Ниже разместите кнопку Button2 (страница Стандарт) с надписью найти первое слово. В файле LR_2.cpp перед обработчиком щелчка на кнопке дайте объявления

int k1,k2;

unsigned l1,l2;

а в обработчик щелчка на кнопке внесите (курсив)

void __fastcall TForm1::Button2Click(TObject *Sender)

{

Memo1->Lines->Add("НАЙТИ:");

l1=LabeledEdit1->SelLength;

if((k1=FindWord(RichEdit1->Text.c_str(),

LabeledEdit1->SelText.c_str()))>=0)

{Memo1->Lines->Add("Первое слово - с позиции "+IntToStr(k1+1));

RichEdit1->SelStart=k1;

RichEdit1->SelLength=l1;

RichEdit1->SelAttributes->Style=

RichEdit1->SelAttributes->Style<<fsBold;

RichEdit1->SelStart=k1+l1;}

else Memo1->Lines->Add("Нет первого слова!");

}

  1. Ниже разместите LabeledEdit2 (страница Дополнительно). Свойству LabelPosition присвойте значение lpAbove (из выпадающего списка), а раскрыв свойство EditLabel, в подсвойстве Caption впишите второе слово.

  2. Ниже разместите кнопку Button3 (страница Стандарт) с надписью найти второе слово, в обработчик щелчка на которой внесите (курсив)

void __fastcall TForm1::Button3Click(TObject *Sender)

{

l2=LabeledEdit2->SelLength;

if((k2=FindWord(RichEdit1->Text.c_str(),

LabeledEdit2->SelText.c_str()))>=0)

{Memo1->Lines->Add("Второе слово - с позиции "+IntToStr(k2+1));

RichEdit1->SelStart=k2;

RichEdit1->SelLength=l2;

RichEdit1->SelAttributes->Style=

RichEdit1->SelAttributes->Style<<fsBold;

RichEdit1->SelStart=k1+l2;}

else Memo1->Lines->Add("Нет второго слова!");

}

  1. Введенные в компоненты LabeledEdit1 и LabeledEdit2 первое и второе слова в тексте могут оказаться стоящими как второе и первое. Следовательно, введенные слова необходимо упорядочить. Разместите на форме кнопку Button4 (страница Стандарт) с надписью упорядочить, в обработчик щелчка на которой внесите (курсив)

void __fastcall TForm1::Button4Click(TObject *Sender)

{

AnsiString s="";

unsigned d=0;

if(k1>k2){

Memo1->Lines->Add("");

Memo1->Lines->Add("УПОРЯДОЧИТЬ:");

d=k1; k1=k2; k2=d;

d=l1; l1=l2; l2=d;

s=LabeledEdit1->Text;

LabeledEdit1->Text=LabeledEdit2->Text;

LabeledEdit2->Text=s;

Memo1->Lines->Add("Первое слово - с позиции "+IntToStr(k1+1));

Memo1->Lines->Add("Второе слово - с позиции "+IntToStr(k2+1));}

}

  1. Ниже разместите кнопку Button5 (страница Стандарт) с надписью поменять местами, в обработчик щелчка на которой внесите (курсив)

void __fastcall TForm1::Button5Click(TObject *Sender)

{

if(k1>=0&&k2>=0&&f){

f=0; Memo1->Lines->Add("");

Memo1->Lines->Add("ПОМЕНЯТЬ МЕСТАМИ:");

RichEdit1->SelStart=k1;

RichEdit1->SelLength=l1;

RichEdit1->SetSelTextBuf(LabeledEdit2->Text.c_str());

RichEdit1->SelStart=k2+(l2-l1);

RichEdit1->SelLength=l2;

RichEdit1->SetSelTextBuf(LabeledEdit1->Text.c_str());

Memo1->Lines->Add("Второе слово - с позиции "+IntToStr(k1+1));

Memo1->Lines->Add("Первое слово - с позиции "+

IntToStr(k2+1+(l2-l1)));}

}

  1. Проектирование приложения закончим включением в файл LR_2.cpp перед обработчиком щелчка на кнопке Button2 (с надписью найти первое слово) определения функции, которая для строк типа char* ищет одну строку в другой. В случае успеха функция возвращает номер позиции, с которой начинается короткая строка в длинной строке, а в случае неуспеха - возвращает -1.

int FindWord(char*str,char*word)

{ unsigned ls=strlen(str);

for(unsigned i=0; i<ls; i++)

{ bool find=true;

char*w=word; int k=i;

if(str[i]==*w)

{ while(*w) if(*w++!=str[k++])

{ find=false; break;}

if(find) return k-strlen(word);}

}

return -1;

}

  1. По окончании проектирования файл LR_2.cpp будет выглядеть так:

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "LR_2.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

AnsiString MyFName="";

void __fastcall TForm1::N1Click(TObject *Sender)

{

if(MyFName!="")

Memo1->Lines->SaveToFile(MyFName);

else

if(SaveDialog1->Execute())

{

MyFName=SaveDialog1->FileName;

Memo1->Lines->SaveToFile(SaveDialog1->FileName);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::N2Click(TObject *Sender)

{

SaveDialog1->FileName=MyFName;

if(SaveDialog1->Execute())

{

MyFName=SaveDialog1->FileName;

Memo1->Lines->SaveToFile(SaveDialog1->FileName);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::N3Click(TObject *Sender)

{

if(OpenDialog1->Execute())

{

MyFName=OpenDialog1->FileName;

RichEdit1->Lines->LoadFromFile(OpenDialog1->FileName);

}

}

//---------------------------------------------------------------------------

int f=0;

void __fastcall TForm1::Button1Click(TObject *Sender)

{

Memo1->Clear(); RichEdit1->Clear();

LabeledEdit1->Clear(); LabeledEdit2->Clear();

Memo1->SetFocus(); f=1;

}

//---------------------------------------------------------------------------

//Функция поиска слова word в строке str. В случае успеха

//возвращает номер позиции в строке, с которой начинается слово

int FindWord(char*str,char*word)

{ unsigned ls=strlen(str);

for(unsigned i=0;i<ls;i++)

{ bool find=true;

char*w=word; int k=i;

if(str[i]==*w)

{ while(*w) if(*w++!=str[k++])

{ find=false; break;}

//если в строке str есть слово word, то выход из цикла while

//по завершающему нулевому символу слова word в позиции i

if(find) return k-strlen(word);} //вычитаем длину слова word

}

return -1;

}

//----------------------------------------------

int k1,k2;

unsigned l1,l2;

void __fastcall TForm1::Button2Click(TObject *Sender)

{

Memo1->Lines->Add("НАЙТИ:");

l1=LabeledEdit1->SelLength;//находим длину выделенного первого слова

//вызов функцииFindWord()с преобразованием строк

// типа AnsiString к типу char*

if((k1=FindWord(RichEdit1->Text.c_str(),

LabeledEdit1->SelText.c_str()))>=0) //искомое слово выделено

{Memo1->Lines->Add("Первое слово - с позиции "+IntToStr(k1+1));

RichEdit1->SelStart=k1; //ставим курсор перед первым словом

RichEdit1->SelLength=l1; //выделяем первое слово

RichEdit1->SelAttributes->Style=

RichEdit1->SelAttributes->Style<<fsBold; //жирный шрифт

RichEdit1->SelStart=k1+l1;} //ставим курсор после первого слова

//для сохранения выделения

else Memo1->Lines->Add("Нет первого слова!");

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)

{

l2=LabeledEdit2->SelLength;//находим длину выделенного второго слова

//вызов функции FindWord() с преобразованием строк

// типа AnsiString к типу char*

if((k2=FindWord(RichEdit1->Text.c_str(),

LabeledEdit2->SelText.c_str()))>=0) //искомое слово выделено

{Memo1->Lines->Add("Второе слово - с позиции "+IntToStr(k2+1));

RichEdit1->SelStart=k2; //ставим курсор перед вторым словом

RichEdit1->SelLength=l2; //выделяем второе слово

RichEdit1->SelAttributes->Style=

RichEdit1->SelAttributes->Style<<fsBold; //жирный шрифт

RichEdit1->SelStart=k1+l2;} //ставим курсор после второго слова

//для сохранения выделения

else Memo1->Lines->Add("Нет второго слова!");

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button4Click(TObject *Sender)

{

AnsiString s=""; //строка для обмена

unsigned d=0; //беззнаковое целое для обмена

if(k1>k2){ //условие неправильного порядка следования слов

Memo1->Lines->Add("");

Memo1->Lines->Add("УПОРЯДОЧИТЬ:");

d=k1; k1=k2; k2=d;

d=l1; l1=l2; l2=d;

s=LabeledEdit1->Text;

LabeledEdit1->Text=LabeledEdit2->Text;

LabeledEdit2->Text=s;

Memo1->Lines->Add("Первое слово - с позиции "+IntToStr(k1+1));

Memo1->Lines->Add("Второе слово - с позиции "+IntToStr(k2+1));}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button5Click(TObject *Sender)

{

if(k1>=0&&k2>=0&&f){ //проверяем, в тексте ли слова

f=0; Memo1->Lines->Add("");

Memo1->Lines->Add("ПОМЕНЯТЬ МЕСТАМИ:");

RichEdit1->SelStart=k1;

RichEdit1->SelLength=l1;

//ставим второе слово на место выделенного первого слова

RichEdit1->SetSelTextBuf(LabeledEdit2->Text.c_str());

RichEdit1->SelStart=k2+(l2-l1);

RichEdit1->SelLength=l2;

//ставим первое слово на место выделенного второго слова

RichEdit1->SetSelTextBuf(LabeledEdit1->Text.c_str());

Memo1->Lines->Add("Второе слово - с позиции "+IntToStr(k1+1));

Memo1->Lines->Add("Первое слово - с позиции "+

IntToStr(k2+1+(l2-l1)));}

}

//---------------------------------------------------------------------------

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]