русс | укр

Языки программирования

ПаскальСиАссемблерJavaMatlabPhpHtmlJavaScriptCSSC#DelphiТурбо Пролог

Компьютерные сетиСистемное программное обеспечениеИнформационные технологииПрограммирование

Все о программировании


Linux Unix Алгоритмические языки Аналоговые и гибридные вычислительные устройства Архитектура микроконтроллеров Введение в разработку распределенных информационных систем Введение в численные методы Дискретная математика Информационное обслуживание пользователей Информация и моделирование в управлении производством Компьютерная графика Математическое и компьютерное моделирование Моделирование Нейрокомпьютеры Проектирование программ диагностики компьютерных систем и сетей Проектирование системных программ Системы счисления Теория статистики Теория оптимизации Уроки AutoCAD 3D Уроки базы данных Access Уроки Orcad Цифровые автоматы Шпаргалки по компьютеру Шпаргалки по программированию Экспертные системы Элементы теории информации

Из чисел в строки


Дата добавления: 2015-09-15; просмотров: 795; Нарушение авторских прав


 
var
S: String;
I, Code: Integer;
 
begin
Write('Введите число: ');
Readln(I);
Str(I, S);
Writeln('Получилась строка: ', S);
Write('Можно даже сложит ее с собой: ', S+S);
Readln;
end.

Это примеры использования процедур преобразования. А теперь давайте составим более полезную программу, которая уже будут выполнять кое-какие действия. Итак, заадчей, которую мы выполним будет ввод целого числа по символам, с выводом ошибки при вводе недопустимого символа. Работать программа будет так:

  • Читатем цифры до нажатия клавиши .
  • После этого преобразовываем получившееся число в Integer и выводим на экран.

Теперь давайте разберем алгоритм работы такой программы:

  • Читаем символ;
  • Проверяем символ:
    • Это цифра: дополняем временную строку новой цифрой;
    • Это Enter (#13) - преобразуем полученную строку в число и выводим его на экран;
    • Это Esc (#27) - выходим из программы без продолжения дальнейших действий.
    • Иначе - ошибка и мы начинаем сначала;

Текст самой программы:

 
Program N6;
uses Crt;
var
S: String;
C: Char;
I, Code: Integer;
begin
repeat
C := ReadKey;
case C of
'0'..'9': begin
S := S + C;
Write(C);
end;
#13: begin
Val(S, I, Code);
Writeln;
Writeln('Число: ', I);
Writeln;
Readln;
Break;
end;
#27: Break;
end;
until false;
end

 

 

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



  • Записи (record)
  • Файловые типы;
  • Перечисляемые типы;
  • Определяемые пользователем типы;
  • Объекты (object);
  • Некоторые другие (указатели...)

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

Итак, сегодня мы начинаем изучение новых типов, а именно записей или, как они изображаются в Паскале record. Эта тема даст вам мощный инструмет, послужит отличным введением в объектно-ориентированное программирование, как следствие приблизит к программированию под Win32 и расширит ваши возможности как программистов.

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


Работа с записями

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

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

  • Программа может спрашивать и выдавать следующие данные:

1. Фамилия, имя, отчество;

2. Адрес: улица, дом;

3. Телефон;

4. E-mail;

  • Пусть количество адресатов будет ограничено 10ю адресами.

Теперь задумаемся: что нам нужно, чтобы написать такую программу? В первую очередь встает вопрос о хранении вводимых данных. Я не имею ввиду их сохранение на диске - таким мы пока не занимались, это тема следующих выпусков. Нет, наша программа будет хранить данные пока только в памяти компьютера. Но как? В какие переменные она будет их помещать?

Вы знакомы с понятием массива. Но массив может хранить только одну переменную в каждом своем элементе. В принципе, нам и требуется что-нибудь вроде массива, только необходимо, чтобы в каждом его элементе сохранялось 4 переменных. Понятно, что с помощью массивов такого сделать нельзя.

Здесь мы и подходим к понятию записей. На самом деле запись - это контейнер, в котором именно "записано" несколько переменных. Чем-то похоже на массив, только переменные могут быть разных типов, каждая из них имеет свое имя.

Для начала давайте определим типы для наших данных (адрес):

  • Fio: String; {фио}
  • Adress: String: {адрес}
  • Phone: LongInt; {телефон, в виде числа}
  • Email: String; {e-mail}

Как видите, переменных несколько, все они имеют имена и разных типов. Что же делать с такими данными? В принципе, можно эту задачу решить и с одними массивами - завести 4 массива соотв. типов и параллельно сохранять в них переменные. Но это делается гораздо проще, если пользоваться записями.

Запись - это способ объединения нескольких переменных разных типов в одной. Благодаря этому достигается замечательная упорядоченность данных, программы при этом упрощаются и становятся логичнее.

Итак, как же создать запись? Разложу все этапы создания записи по порядку.

В первую очередь обращаю внимание на то, что записи описываются в разделе type, который подобен известным нам разделам var или const. В этом разделе описываются все типы, определяемые пользователем.

Описываются записи с помощью служебного слова record, перед которым идет имя записи:

Type

AdressItem = Record

После описываются все переменные, которые будут содержаться в записи, подобно тому, как они описываются в разделе var. Завершается запись словом end;. Вот пример записи, необходимой для нашей программы:

Type

AdressItem = Record

Fio: String;

Adress: String;

Phone: LongInt;

Email: String;

end;

Как видите, описать запись совсем не сложно. Кроме того, обращаю внимание, что создав в программе запись вы получаете новый тип и нужно создать переменные этого типа. Здесь тоже нет ничего сложного. После того, как вы опишете запись в разделе type, можно создать переменные нового типа в разделе var:

Var

A,B: AdressItem;

И все. Теперь вы имеете две записи. Но две записи - это мало, по условию нам нужно 10 записей (у нас адресная книжка на 10 адресов). Нет ничего проще! Вспоминаем массивы и их возможности - объединение группы переменных одного типа. Вот и сделаем массив из созданной записи:

Var

Book: Array [1..10] of AdressItem;

Вот и все, теперь мы имеем целых десять записей. При этом каждый элемент массива Book в свою очередь содержит другие, собственные переменные. Вроде бы все просто и уже понятна работа записей, но как теперь добраться до переменных, которые находятся внутри записи? Это тоже чрезвычайно просто.

Существует два способа обращения к элементам записи. Пока немного отойдем от созданного массива и поработаем с такой переменной:

Var

A: AdressItem;

Теперь, допустим, мы хотим прочитать с клавиатуры все поля записи и внести в переменные, которые внутри A значения. Для этого нужно обратиться к полям записи одним из следующих способов.

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

Var

A: AdressItem;

Begin

withA do

Write('ФИО: ');

Readln(Fio);

Write('Адрес: ');

Readln(Adress);

Write('Телефон: ');

Readln(Phone);

end;

end.

Думаю, синтаксис констркукции with понятен:

  • with _имя_записи_ do
  • .... действия с ее полями (ее переменными) .....
  • end;

Это очень просто, но если вы всеже не поняли, как идет обращение к записи через использование with, думаю в примере, который будет сегодня в выпуске, вы полностью в этом разберетесь.

2. Итак, второй способ обращения к полям записи. Он еще проще и гораздо компактнее. Суть его в следующем:

  • · К полю записи можно обратиться, указав имя записи и через точку имя поля.

В нашем примере с записью A программа принимает следующий оборот:

Var

A: AdressItem;

Begin

Write('ФИО: ');

Readln( A.Fio );

Write('Адрес: ');

Readln( A.Adress );

Write('Телефон: ');

Readln( A.Phone );

end.

Это, на мой взгляд совсем просто. Теперь давайте ворнемся к нашей программе "Записная книжка" и к нашему массиву из записей. Перед тем, как подготовиться в написанию самой программы давайте посмотрим, как можно с помощью приведенных выше двух способов обратиться к полям записи, которая является элементов массива. У нас это массив Book (Книжка).

Способ первый - с помощью with. Читаем первый элемент массива Book:

  • With Book[1] do begin
  • Write('ФИО: ');
  • Readln(Fio );
  • Write('Адрес: ');
  • Readln(Adress );
  • Write('Телефон: ');
  • Readln(Phone );
  • end.

Способ второй - с помощью оператора "точка". Читаем первый элемент массива Book:

  • begin

Write('ФИО: ');

Readln(Book[1].Fio );

Write('Адрес: ');

Readln(Book[1].Adress );

Write('Телефон: ');

Readln(Book[1].Phone );

end.

Разобрались? Надеюсь, что да. Поверьте, здесь нет ничего сложного. Если все-таки немножко непонятно, ничего страшного - дальше разберетесь.

Ну а теперь пришло время написать небольшую программку, которая будет работать с записями. Продолжая тему сегодняшнего урока я приведу текст предложенной програмы "Адресная книжка". Итак, получается такая вот программка:

 
Program Adress_Book;
uses Crt;
type
AdressItem = record
Fio: String;
Adress: String;
Phone: LongInt;
Email: String;
end;
var
Book: Array [1..10] of Adressitem;
Nums, I: Byte;
Code: Integer;
C: Char;
Quit: Boolean;
{ процедура добавления новой записи }
Procedure New_Item;
var
F, A, Em: String;
Ph: LongInt;
begin
ClrScr;
Inc(Nums);
if Nums > 10 then
begin
Write('Максимальное количество записей!');
exit; {выход из процедуры}
end;
Writeln('Запись N', Nums); Writeln;
Write('Введите ФИО: ');
Readln(F);
Write('Введите адрес: ');
Readln(A);
Write('Введите телефон: ');
Readln(Ph);
Write('Введите E-mail: ');
Readln(Em);
Writeln;
with Book[Nums] do
begin
Fio := F;
Adress := A;
Phone := Ph;
Email := Em;
end;
Write('Новая запись успешно добавлена!');
end;
{ процедура отображения данных отдельной записи }
Procedure List_Item(N: Byte);
begin
if N > Nums then
begin
Write('Неправильный номер записи');
exit; {выход из процедуры}
end;
With Book[N] do
begin
Writeln('Запись N', N); Writeln;
Writeln('ФИО: ', Fio);
Writeln('Aдрес: ', Adress);
Writeln('Tелефон: ', Phone);
Writeln('E-mail: ', Email);
Writeln;
end;
Readln;
end;
begin
Quit := False;
Nums := 0;
repeat
ClrScr;
Writeln('Программа "Записная книжка"');
Writeln('==========================='); Writeln;
Writeln('Записи: ');
Writeln('--------------------');
if Nums = 0 then Writeln('Записей нет. Книжка пуста.')
else
For I := 1 to Nums do
Writeln(I, ' - ФИО: ', Book[I].Fio);
Writeln('--------------------'); Writeln; Writeln;
Writeln('''a'' - добавить запись');
Writeln('Номер - показать запись');
Writeln('Esc - выход');
Writeln;
Write('Ваш выбор: ');
C := ReadKey;
case C of
'1'..'9': begin
Val(C, I, Code);
List_Item(I);
end;
'a': New_Item;
#27: Quit := true;
end;
until Quit;
end.

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

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

  • New_Item - добавляет новую запись;
  • List_Item - отображает одну из записей.

Остальное - это главный блок программы, раздел repeat - until. Теперь вкратце обо всех частях программы.

Во-первых, разберемся с переменными. Как Вы видите, их очень мало, кроме того - две вообще не имеют непосредственного отношения к программе. Это I (только для цикла), а также Code, которая используется лишь для возвращения кода возможной ошибки в процедуре Val (см. пред. выпуск).

Итак, вы видите, что в самом начале описана сама запись. Далее - создается массив Book, нового созданного типа AdressItem, то есть каждый его элемент - это запись AdressItem. Дальше - переменная Nums, которая содержит текущее количество записей в нашей адресной книге. Переменная C - это для выбора элемента меню. Quit: Boolean - проверка на выход. Цикл у нас идет как раз исходя из этой переменной. Если пользователь решил выйти из записной книжки, то Quit просто становиться true и основной цикл прекращается, программа останавливается.

Ну а теперь о процедурах. Первая - New_Item. Она демонстрирует работу по занесению значений в отдельную запись. В самом ее начале увеличивается переменная Nums, что означает добавление новой записи (на одну становиться больше). Кроме того, пере тем, как произвести увеличение этой переменной, проверяется - она больше 10? Если да, то достигнут максимум сообщений и больше добавлять нельзя, о чем процедура своевременно оповещает и завершает свою работу без выполнения дальнейших действий, для чего служит операция exit;

Дальше - читаются несколько переменных. После этого считанные значения заносятся в поля записи. Вот и все.

Процедура List_Item выводит данные конкретной записи под номером N, который передается ей в качестве параметра. Как и пред. процедура, она сначала проверяет N на правильность (не больше ли, чем всего записей в книжке?) и если она верна, то просто распечатывает поля записи, которая лежит в массиве Book под номером N. Readln, который стоит последней строчкой, думаю, пояснений не требует :)

Ну а теперь о главном теле программы и ее основном цикле. В самом начале программы основным переменным присваиваются значения, порядка ради:

  • Quit := False; { это значит, что выхода пока нет }
  • Nums := 0; { записей нуль, книжка пуста }

После этого начинается сам цикл, о котором уже упоминалось выше. Работа, которая в нем выполняется тоже очень проста - все сводиться к очистке экрана, распечатке меню программы и действия выбора. Общий план таков:

  • Очищаем экран;
  • Распечатываем меню программы;
  • Распечатываем записи книжки в виде "N_записи - ФИО: _поле_Fio_записи_", то есть выводим список имеющихся имен. При этом, как видите, сначала проверяется переменная Nums и если она равна нулю (записей нет), то ничего печататься не будет, а выведется строка "Записей нет. Книжка пуста". И еще - обратите внимание, в этом действии я использую точку - Book[I].Fio - для обращения к полю записи, а не конструкцию With ... do. Здесь это гораздо удобнее.
  • Читается символ (Помните, функция ReadKey из модуля Crt не требует подтверждения ввода нажатием Enter.
  • В зависимости от того, чему равна эта переменная, вызывается определенная процедура, либо осуществляется выход.

Это все. Как видите, программа совершенно не сложная. Зато хорошо демонстрирует работу с записями.

Ну а теперь о том, почему я не доработал эту программу, а также о том, что еще с ней можно сделать. Уважаемые друзья! Эта программа - тема и следующего выпуска тоже, когда мы будем проходить работу с файлами. Тогда мы усовершенствуем ее, чтобы Записной книжкой можно было реально пользоваться - будем сохранять базу сообщений в отдельном файле, а также добавим несколько функций.

В связи с этим формируется домашнее задание, которое вам необходимо выполнить для успешного освоения материала следующего выпуска. Оно заключается в том, чтобы добавить в эту книжку несколько новых функций. Присылать мне эти задания не нужно, это только для вас. НО: если вы их не выполните, то материал следующего выпуска понять будет довольно сложно, так как я НЕ БУДУ ПРИВОДИТЬ исходный код некоторых процедур, задаваемых на дом.

Итак, домашнее задание для самостоятельной работы:

  • Напишите процедуру УДАЛЕНИЯ ЛЮБОЙ ПО НОМЕРУ ЗАПИСИ из массива (подсказка: вспоминайте алгоритм сдвига элементов по массиву из пред. выпусков);
  • Добавьте возможность ПОИСКА ИНФОРМАЦИИ по всей записной книжке, то есть осуществите возможность найти телефон и посмотреть все его данные; найти телефон по ФИО; найти ФИО по адресу и т.п. (подсказка: вспоминайте работу со строками!)
  • В программе есть небольшая ошибка. Найдите и исправьте ее. Интересно, кто сообразит :)) Об этом можете мне написать (только не присылайте исправленные исходники, мне они полезны не будут).

В прошлом выпуске мы с вами начали писать программу, которая и должна была стать основопологающей в наших дальнейших действиях. Программа называлась "Записная книжка", манипулировала с типом record и еще содержала маленькую ошибочку, которую, кстати, многие заметили.

Обратите внимание на этот код:

 
......
C := ReadKey;
case C of
'1'..'9': begin
Val(C, I, Code);
List_Item(I);
end;
'a': New_Item;
#27: Quit := true;
end;
......

В этом вся собака зарыта. Дело в том, что в условии упоминается о работе с 10-ю записями, а этот алгоритм позволяет использовать всего девять, так как вообще не умеет читать двухзначные числа. Как решить этот вопрос - Ваша задача! Программирование вообще без задач, которые нужно решать, не обходиться...

Ну а мы интенсивно двигаемся дальше. Сегодня - как и было обещано, файлы. Пока только теория, которую вам нужно усвоить (ее довольно много), практика будет в следующем выпуске.


Работа с файлами

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

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

1. Создание (описание) файловой переменной;

2. Связывание этой переменной с конкретным файлом на диске или с устройством ввода-вывода (экран, клавиатура, принтер и т.п.);

3. Открытие файла для записи либо чтения;

4. Действия с файлом: чтение либо запись;

5. Закрытие файла.

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

1. CON - консоль (экран-клавиатура), то есть по записи в это устройство мы будем получать информацию на экран, при чтении информации из этого устройства, будем читать данные с клавиатуры.

2. PRN - принтер. При записи в это устройство вы получите информацию на принтер.

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


Типы файловых переменных

Перед тем, как начинать работу с файлами, давайте посмотрим, какие существуют переменные для работы с ними. В Turbo Pascal имеется три типа таких переменных, которые определяют тип файла. Вот эти типы:

1. Text - текстовый файл. Из переменной такого типа мы сможем читать строки и символы.

2. File of _любой_тип_ - так называемые "типизированные" файлы, то есть файлы, имеющие тип. Этот тип определяет, какого рода информация содержится в файле и задается в переметре _любой_тип_. К примеру, если мы напишем так:

F: File of Integer;

То Паскаль будет считать, что файл F содержит числа типа Integer; Соответсвенно, читать из такого файла мы сможем только переменные типа Integer, ровно как и писать. Напишем так:

Type

A = record

I,J: Integer;

S: String[20];

end;

Var

F: File of A;

То получим очень интересную картину, когда файл содержит в качестве элементов записи. Мы сможем их читать, писать и производить с ними действия. Именно этим мы и займемся в процессе модификации нашей программы "Записная книжка".

3. File - нетипизированный файл. Когда мы указываем в качестве типа файла просто File, то есть без типа:

F: File;

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

Итак, разобрались с типами файлов. Теперь давайте по порядку разбирать действия, применяемые для работы с файлами. Я говорил о них выше.


Связывание переменной с файлом

Самый универсальный шаг. Выполняется одной и той же процедурой для всех типов файлов, а именно процедурой Assign:

Assign(_переменная_файлового_типа_, 'путь к файлу');

Как видите, в качестве параметров задаются переменная либого файлового типа и строка - путь к файлу, который, по правилам DOS, не может быть длиннее 79 символов. Вот пример использования assign:

 
var
T: Text;
F1: File of Byte;
F2: File;
begin
Assign(T, '1.txt');
Assign(F1, 'C:\Programm\Tp\2.txt');
Assign(F2, 'F:\usr\bin\apache\conf\httpd~1.con');
..........

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


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

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

Тем не менее этот процесс не сложен и заключается в использовании одной из трех имеющихся процедур:

1. Reset(_любая_файловая_переменная_);

Открыват файл на чтение. В качестве параметра - файловая переменная любого из перечисленных выше типов. Это может быть текстовый, типизированный либо не типизированный файл. В случае с текстовым файлом, он открывается только на чтение. В случае с типизированным и нетипизированным файлом - он открывается на чтение и запись.

2. Append(T: Text);

Эта процедура открывает текстовый файл (только текстовый!) на запись. Выше я сказал, что Reset при задании параметра типа Text не позволит писать в него данные, открыв файл лишь для чтения. То есть если вы используете текстовый файл и хотите производить в него запись, нужнo использовать Append. Если чтение - Reset. В остальных случаях дело обходиться одной процедурой Reset.

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

3. ReWrite(F) - создает новый файл либо перезаписывает существующий. Будьте осторожны, если не хотите случайно удалить нужный файл. Напомню, файл, открытый с помощью этой процедуры будет полностью перезаписан.

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

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

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

Оформляются ключи следующим образом: в скобках комментариев "{}" первым символом после открывающей скобки "{" ставиться знак доллара "$", после чего указывается имя ключа и его значение. Нас интесует ключ, который выключает вывод ошибок ввода-вывода, называется он "I". Выглядит все это следующим образом:

{$I+} - включение вывода ошибок

{$I-} - выключение вывода ошибок

По сути дела осутствие файла - это ошибка, которая возвращается функцией IOResult. Если же эта функция возвращает 0, то файл успешно открыт, без ошибок. Вот и вырисовывается последовательность действий, необходимых для проверки на наличие файла:

1. Связываем переменную с файлом;

2. Выключаем вывод ошибок на экран - {$I-}

3. Окрываем файл необходимой нам процедурой;

4. Включаем вывод ошибок {$I+} - пусть будет для дальнейшего отслеживания таковых;

5. Проверяем, если IOResult возвращает нуль, то все было путем и файл открыт. Иначе выводим ошибку.

Вот пример такой программы:

 
var
T: Text;
S: String;
begin
Write('Enter filename: ');
Readln(S);
Assign(T, S);
{$I-}
Reset(T); { открываем файл для чтения }
{$I+}
if IOResult <> 0 then { если не нуль, то была ошибка }
begin
Write('Error when open file!');
Halt;
end;
{ иначе все в порядке, продолжаем }
..........
end.


Закрытие файла

Выше я говорил о том, зачем нужно закрывать файл и когда надо это делать. Закрытие файла производиться с помощью процедуры Close(F), где F - это переменная файлового типа. Эта процедура одна для всех типов файлов.


Запись и чтение файлов. Часть I

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

Чтение файлов. Чтение файлов производится с помощью отлично известных нам процедур Read и Readln. Они используются также, как и при чтении информации с клавитуры. Отличие лишь в том, что перед переменной, в которую помещается считанное значение, указывается переменная файлового типа (дескриптор файла):

Read(F, C);

Здесь F - дескриптор файла, C - переменная (Char, String - для текстовых, любого типа - для типизированных файлов).

Также сразу хочу упомянуть о одной, пожалуй самой главной функции при чтении файлов. Это функция поверки на конец файла - Eof(F): Boolean;. В качестве параметра - файловая переменная любого типа. Функция возвращает TRUE если достигнут конец файла и FALSE иначе. Здесь все очень просто, демонстрации ради давайте напишем небольшую программку. Пусть имеем текстовый файл. Давайте его распечатаем и заодно посчитаем, например, количество пробелов:

 
var
T: Text;
С: Char;
Spaces: Word;
S: String[79]; { 79-макс. длина пути в DOS }
begin
Write('Enter filename: ');
Readln(S);
Assign(T, S);
{ открываем файл для чтения }
{$I-}
Reset(T);
{$I+}
{ если не нуль, то была ошибка }
if IOResult <> 0 then
begin
Write('Error when open file ', S, ' !');
Halt;
end;
{ иначе все в порядке, продолжаем }
{ ЦИКЛ: пока НЕ КОНЕЦ ФАЙЛА }
While (not Eof(T)) do
begin
{ читаем из файла переменную }
Read(T, C);
{ если пробел, увеличиваем счетчик }
If C = ' ' then Inc(Spaces);
Write(C);
end;
Writeln('КОЛИЧЕСТВО ПРОБЕЛОВ: ', Spaces);
Readln;
end.

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

Запись в файлы. Вы еще не догадались? Запись в файлы производиться точно так же, как и запись на экран - с помощью процедур Write и Writeln. Как и в случае с чтением, перед записываемой в файл переменной указывается тескриптор файла:

Write(F, S);

Здесь F - дескриптор, S - переменная.

При этом, естественно, переменная должна соответсвовать типу файла. Примера ради давайте составим еще одну небольшую программку, которая покажет работу с файлами. На сей раз уже используем типизированные файлы, а имеено состоящие из чисел. Итак, мы имеем файл, в котором содержаться числа типа Integer. Давайте отсортируем эти числа в файле по возрастанию.

План дейтсвий:

  • Отрываем типизированный файл из Integer; (проверяем на ошибку и т.п.)
  • Читаем все числа в массив (считываем, пока не конец файла)
  • Сортируем массив по возрастанию;
  • Записываем отсортированный массив обратно в файл.

Получается такая программа:

 
Program Sorting;
uses Crt;
var
F: File of Integer;
I, J, M: Word;
Mas: Array[1..500] of Integer;
S: String;
begin
ClrScr;
Write('Enter filename: ');
Readln(S);
{ открываем файл }
Assign(F, S);
{$I-}
Reset(F);
{$I+}
if IOResult <> 0 then
begin
Write('Error when open file!');
Halt;
end;
{ пока не конец файла, читаем массив }
While (not Eof(F)) do
begin
Inc(M);
Read(F, Mas[M]);
Write(Mas[M], ' ');
end;
{ сортируем массив по возрастанию }
For I := 1 to M do
For j := 1 to M do
if Mas[I] < Mas[J] then
begin
inc(mas[j], mas[i]);
mas[i] := mas[j]-mas[i];
dec(mas[j], mas[i]);
end;
Writeln; Writeln('=============================================');
{ перезаписываем файл }
ReWrite(F);
For I := 1 to 100 do
begin
Write(Mas[I], ' ');
Write(F, Mas[i]);
end;
Writeln; Write('Elements in file: ', M);
Close(F);
Readln;
end.

Программа очень проста и хорошо демонстрирует работу с типизированными файлами. В качестве сортировки массива я использую метод пузырька, чтобы перезаписать файл использую ReWrite. Вроде не должно возникать никаких сложностей... Будут проблемы, пишите. Ну а на сегодня, пожалуй, все. Этой информации вам будет достаточно, в следующем выпуске займемся, как я уже сказал, нетипизированными файлами и продолжим писать программу "Записная книжка".

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

Итак, в чем же разница? Чтобы лучше это понять, советую вспомнить как производиться чтение из типизированных файлов. Работая с ними, мы заранее знаем с переменными какого типа мы имеем дело и, соответсвенно, без проблем читаем эти переменные. Здесь же все наоборот: работая с файлами без типа мы не знаем, что за данные в них находятся и в переменные какого типа их надо помещать. Вы не поняли? Вот смотрите. Имеем файл, в котором находиться два элемента: 1) число "100" (символ "d" - насчет ASCII кодов см. пред. выпуски), 2) строка - "Here is string". Как прочитать из этого файла две переменные разных типов? Вспомните еще раз - если мы зададим этот файл как типизированный или текстовый, то сможем читать либо только числа (File of Integer) либо символы и строки (Text).

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

Как же реализуется чтение данных разного типа? Дело в том, что читая данные из файла без типа мы получаем блоки информации, которые составляют обычный набор байт. Указывая переменную, в которую эти байты надо поместить, мы как бы "на ходу преобразуем" эти данные к нужному типу. Вернемся к примеру выше. Имеем файл с такой строкой:

dHere is string

Номер буквы "d" в таблице символов - 100. Если мы прочитаем из файла один байт, указав, что его нужно поместить в переменную типа Byte, эта переменная приобретет значение 100. Если же мы будем читать этот байт в переменную типа Char, то получим символ "d". Вот и вся особенность, согласитесь, иногда довольно полезная. Скажу, что таким образом очень удобно читать записи, особенно разные.

Ну а теперь давайте посмотрим, каким образом производиться работа с файлами без типа.


Чтение из файлов без типа

Сама процедура связывания файловой переменной с внешним файлом и его открытие ничем чем отличаются от обычного порядка действий. Разве что переменная в данном случае должна иметь тип File; , то есть быть файлом без типа.

 
var
F: File;
begin
{ связываем файл с переменной }
Assign(F, '1.txt');
Reset(F);
end.

Чтение происводиться с помощью процедуры BlockRead. Посмотрим, как она работает:



<== предыдущая лекция | следующая лекция ==>
Список_переменных: тип | BlockRead(F: File, Buf: Var, Size: Word, Result: Word)


Карта сайта Карта сайта укр


Уроки php mysql Программирование

Онлайн система счисления Калькулятор онлайн обычный Инженерный калькулятор онлайн Замена русских букв на английские для вебмастеров Замена русских букв на английские

Аппаратное и программное обеспечение Графика и компьютерная сфера Интегрированная геоинформационная система Интернет Компьютер Комплектующие компьютера Лекции Методы и средства измерений неэлектрических величин Обслуживание компьютерных и периферийных устройств Операционные системы Параллельное программирование Проектирование электронных средств Периферийные устройства Полезные ресурсы для программистов Программы для программистов Статьи для программистов Cтруктура и организация данных


 


Не нашли то, что искали? Google вам в помощь!

 
 

© life-prog.ru При использовании материалов прямая ссылка на сайт обязательна.

Генерация страницы за: 0.017 сек.