Ввод - вывод числовых данных




Работа с символьной информацией

 

Для понимания работы с компонентами рассмотрим наиболее часто использующиеся компоненты – компоненты для ввода-вывода символьной информации.

Ввод данных

Самый простой компонент для ввода данных пользователем – это Edit. Вводимый пользователем (или выводимый программой) текст содержится в поле Text. Выравнивание текста невозможно. Свойство MaxLength определяет максимальную длину вводимого текста (при значении 0 длина текста не ограничена).

Типичные комбинации “горячих клавиш” помогают пользователю при вводе копировать выделенный текст из поля в буфер обмена, а также вырезать и вставлять текст из буфера (Ctrl-C, Ctrl-X, Ctrl-V).

С точки зрения программы введенная строка имеет тип AnsiString, это специальный строковый тип данных. Рассмотрим операции определенные над строками.

Операция присваивания обозначается символом равенства. Например, можно объявить строковую переменную и присвоить ей строку введенную в поле Edit1: AnsiString str; str = Edit1->Text; а можно и присвоить строке какое-либо значение, а затем передать его в поле: str = “Текст”; Edit1->Text = str; или сразу Edit1-> Text = “Текст”; Допустимым также является присвоение строке числа, например, оператор Label1 -> Caption = 256; преобразует число в строку и в символьном виде выведет его на экран.

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

str = “Вы ввели: “ + Edit1.Text;

Label1->Caption = str;

Для экспериментов со строками можно создать приложение с двумя полями для ввода (рис.13): Edit1 и Edit2, меткой Label1 для вывода результата и кнопкой Button1 (по щелчку на кнопке будут выполняться те или иные действия).

Теперь двойным щелчком на кнопке создать пустой обработчик события и записать в него оператор:

void __fastcall TForm1::Button1Click(TObject *Sender)

{ Label1->Caption = Edit1->Text +

Edit2->Text; }

после компиляции и запуска программы можно

проверить как работает операция конкатенации.

Можно также присоединить к строке число (оно будет преобразовано к символьному типу), например, оператор Label1->Caption = Edit1->Text + Edit2-> Text + 32;будет работать, а вот, наоборот, прицепить к числу строку не удастся. Оператор Label1-> Caption = 32 + Edit1->Text + Edit2-> Text; работать не будет и если необходимо, чтобы программа преобразовала число и присоединила его к строке, то надо использовать специальную функцию. Следующий оператор в обработчике события

void __fastcall TForm1::Button1Click(TObject *Sender)

{ Label1->Caption= IntToStr(32)+

Edit1->Text+Edit2->Text; }

будет работать как показано на рисунке 14.

Операции отношения (==, !=, >, <, >=, <=) позволяют сравнивать строки. Чтобы лучше понять работу операций можно создать обработчик со следующим кодом:

void __fastcall TForm1::Button1Click(TObject *Sender)

{ if (Edit1->Text < Edit2->Text)

Label1->Caption="Строка 1 меньше";

Else

if (Edit1->Text > Edit2->Text)

Label1->Caption="Строка 2 меньше";

Else

Label1->Caption="Равны"; }

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

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

Операция индексации (квадратные скобки) позволяет обращаться к символам в строке по номеру (индексы начинаются с 1). Например, если AnsiString str=”МЭИ”; то str[1] - это’М’ str[2] - это ‘Э’ и т.д.

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

Длина строки – функция Length. Например, результатом работы операторов AnsiString str; int n; str = “МЭИ+ГПИ”; n = str.Length(); будет n=7. Доступ к функциям осуществляется через строку и операцию точка ‘.’. Следующий код, написанный для формы, в которой одно поле Edit1, метка Label1 и кнопка Button1 (рис. 16) демонстрирует работу функции:

void __fastcall TForm1::Button1Click(TObject *Sender)

{ int n; n=(Edit1->Text).Length();

Label1->Caption=n; }

Теперь можно будет решать и более сложные задачи, например, во введенной строке заменить все пробелы на знак подчеркивания (рис. 17):

void __fastcall TForm1::Button1Click (TObject *Sender)

{ AnsiString str; int i, n;

str=Edit1->Text;

n=str.Length();

for (i=1; i<=n; i++)

if (str[i]==' ')

str[i]='_';

Label1->Caption= str;

}

Функция Pos возвращает номер символа, с которого в строке начинается заданная подстрока (первый символ имеет номер 1, возвращается первая подстрока, 0 означает, что подстрока не найдена).

str= “Я учусь в МЭИ”;

i = str.Pos("в"); //вернется значение i=9

Функция SubString возвращает подстроку (часть строки), начиная с указанного номера (первый параметр) заданное количество символов (второй параметр). Если второй параметр превышает количество символов в строке, то возвращается меньшее количество.

str= str.SubString(1,i+1)+"МГУ"; //теперь “Я учусь в МГУ”

Теперь предыдущую задачу (заменить пробелы знаками подчеркивания) можно решить и по другому:

void __fastcall TForm1::Button1Click(TObject *Sender)

{ AnsiString str; int d;

str=Edit1->Text;

d=str.Pos(" ");//d – определяем позицию первого пробела

while (d>0)

{ str=str.SubString(1,d-1) + "_" +

str.SubString(d+1,str.Length()-d);

d=str.Pos(" ");//d – позиция следующего пробела

}

Label1->Caption= str; // Вывод результата

}

Этот код находит в строке подстроку состоящую из одного символа – пробела и получает новую строку, склеивая часть строки до пробела со знаком подчеркивания и с частью строки после пробела. Если пробел расположен на первой позиции в строке, то функция Substring(1,d-1) вернет пустую строку (до пробела ничего нет) и, если пробел – последний символ в строке также вернется пустая строка (после пробела ничего нет), поэтому данный код всегда работает корректно. Эту версию программы (с использованием функций) легко переделать так, чтобы не только один символ заменялся другим, но и чтобы любая группа символов заменялась на любое количество других символов.

Функция Delete удаляет из строки, начиная с заданной позиции (первый параметр) заданное число символов (второй параметр). Например, следующий код удаляет из строки все пробелы (рис. 18):

void __fastcall TForm1::Button1Click(TObject *Sender)

{ AnsiString str; int d;

str=Edit1->Text;

d=str.Pos(" ");

while (d>0)

{ str.Delete(d,1);

d=str.Pos(" ");

}

Label1->Caption= str;

}

Конечно, удалять из строки можно не только пробелы, но и любые другие символы, это достаточно простая задача. При работе с текстом может потребоваться более сложная задача: удалить из строки начальные и конечные пробелы, а все слова разделить ровно одним пробелом.Для ее решения можно воспользоваться следующим кодом (результат работы представлен на рисунке 19, а для наглядности слова разделены не пробелами, а знаками подчеркивания):

void __fastcall TForm1::Button1Click(TObject *Sender)

{ AnsiString str; int d,i;

str=Edit1->Text;

// Удаляем начальные пробелы

d=str.Pos("_");

while (d==1)

{ str.Delete(1,1);

d=str.Pos("_"); }

// Удаляем конечные пробелы

// (т.е. в последней позиции)

d=str.SubString(str.Length(),1).Pos("_");

while (d==1)

{ str.Delete(str.Length(),1);

d=str.SubString(str.Length(),1).Pos("_"); }

// Удаляем лишние пробелы между словами

i=str.Pos("_"); // позиция первого пробела

d=i; // d – позиция пробела, который остается в строке

while (i>0) // цикл продолжается пока находим пробелы

{ i=str.SubString(d+1,str.Length()-d).Pos("_");

if (i==1)

str.Delete(d+1,1); //удаляем пробел после d

else d=d+i; }

}

Функция Insert вставляет в строку подстроку (первый параметр функции) в заданную позицию (второй параметр).

Например, разделить все символы строки символом ‘*’ (рис. 20):

void __fastcall TForm1::Button1Click(TObject *Sender)

{ AnsiString str; int d;

str=Edit1->Text;

// d – номер символа после

// которого должна быть звездочка

d=1;

while (d<str.Length())

{ str.Insert("*",d+1);

d=d+2; }

Label1->Caption= str;

}

Функции UpperCase и LowerCase возвращают строку только из заглавных или строчных букв соответственно:

str=str.UpperCase(); // перевод строки в заглавные буквы

str=str.LowerCase(); // перевод строки в строчные буквы

Компонент Memo

В более сложных задачах приходится обрабатывать не одну символьную строку, а иметь дело с целыми наборами строк, т.е. с текстом. Для работы с несколькими строками текста можно использовать компонент Memo – окно для многострочного редактирования. Основное его свойство Lines – набор строк. К отдельным строкам можно обращаться по индексу (нумерация с 0): Memo1->Lines->Strings[i] – строка с номером i.

Пользователь может вводить текст в окно Memo, а программа может извлечь из него любую строку и применять к ней любые функции для работы со строками, например,:

AnsiString str; int i=0;

str=Memo1->Lines->Strings[i]; // нулевая строка

str=str.UpperCase(); // перевод строки в верхний регистр

Memo1->Lines->Strings[i]=str; // заменить строку на новую

Количество строк в компоненте хранится в свойстве Count:

int n; n= Memo1->Lines->Count;

Этот компонент удобно использовать и для вывода информации, когда она занимает несколько строк. Например, вводится строка, все слова в которой разделены пробелами, найти и вывести по одному отдельные слова. На рисунке 21 представлена форма приложения, которую удобно использовать для решения данной задачи. Edit1 – поле для ввода строки, Memo1 – компонент для вывода отдельных слов, по щелчку на кнопке Button1 (Caption=”Слова”) из заданной строки будут выделяться слова и по очереди добавляться в очередную линию компонента Memo1.

Memo1->Lines->Add(“строка”); - метод добавления строки к уже имеющимся в окне Memo1. Метод Memo1-> Clear(); - позволяет очистить компонент, удалив из него весь текст. Так как пользователь может вводить в Edit1 достаточно длинные строки, состоящие из большого количества слов, следует для Memo1 установить свойство ScrollBars = ssVertical (вертикальная линия прокрутки). Если после этого ввести в обработчик события OnClick кнопки следующий код, то результат работы программы будет выглядеть как на рисунке 22:

void __fastcall TForm1::Button1Click(TObject *Sender)

{ AnsiString str, slovo; int d;

Memo1->Clear(); str=Edit1->Text;

while (str.Length()>0)

{ d=str.Pos(" "); // d – позиция пробела

if (d==1) str.Delete(1,1);

else

{ if (d>0)

{slovo=str.SubString(1,d-1);

str.Delete(1,d); }

else

{ slovo=str.SubString(1,str.Length());

str.Delete(1,str.Length()); }

Memo1->Lines->Add(slovo);

}

}

}

Ввод - вывод числовых данных

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

На рисунке 23 представлена форма приложения, которое демонстрирует ввод чисел и применение к ним арифметических операций. Например, по щелчку на кнопке Button1 производится сложение чисел:

void __fastcall TForm1::Button1Click(TObject *Sender)

{ float a,b,c;

a=StrToFloat(Edit1->Text);

b=StrToFloat(Edit2->Text);

c=a+b;

Label1->Caption=

FloatToStr(c); }

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

void __fastcall TForm1::Button2Click(TObject *Sender)

{ float a,b,c; AnsiString str;

a=StrToFloat(Edit1->Text);

b=StrToFloat(Edit2->Text);

c=a*b; str = FloatToStr(c);

// Проверка наличия запятой

if (str.Pos(",")>0)

Label1->Caption=str.SubString(1,str.Pos(",")+3);

else

Label1->Caption=str;

}

В примерах были использованы функции преобразования строки в вещественное число - StrToFloat и обратного преобразования вещественного числа в строку символов – FloatToStr. При работе с целыми числами следует использовать: IntToStr – число в строку и StrToInt – строка в целое число.

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



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2018-01-27 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: