Функция ВПР
Excel для Microsoft 365 Excel для Microsoft 365 для Mac Excel для Интернета Excel 2021 Excel 2021 для Mac Excel 2019 Excel 2019 для Mac Excel 2016 Excel 2016 для Mac Excel 2013 Excel 2010 Excel 2007 Excel для Mac 2011 Excel Starter 2010 Еще. Меньше
Совет: Попробуйте использовать новую функцию ПРОСМОТРX, улучшенную версию функции ВПР, которая работает в любом направлении и по умолчанию возвращает точные совпадения, что делает ее проще и удобнее в использовании, чем предшественницу.
Находите данные по строкам в таблице или диапазоне с помощью функции ВПР. Например, можно найти цену автомобильной детали по ее номеру или найти имя сотрудника по его идентификатору.
Самая простая функция ВПР означает следующее:
=ВПР(искомое значение; место для его поиска; номер столбца в диапазоне с возвращаемым значением; возврат приблизительного или точного совпадения — указывается как 1/ИСТИНА или 0/ЛОЖЬ).
Совет: Секрет функции ВПР состоит в организации данных таким образом, чтобы искомое значение (Фрукт) отображалось слева от возвращаемого значения, которое нужно найти (Количество).
Технические подробности
Используйте функцию ВПР для поиска значения в таблице.
ВПР(искомое_значение, таблица, номер_столбца, [интервальный_просмотр])
- =ВПР(A2;A10:C20;2;ИСТИНА)
- =ВПР(«Иванов»;B2:E7;2;ЛОЖЬ)
- =ВПР(A2;’Сведения о клиенте’!A:F;3;ЛОЖЬ)
Имя аргумента
искомое_значение (обязательный)
Значение для поиска. Искомое значение должно находиться в первом столбце диапазона ячеек, указанного в аргументе таблица.
Например, если таблица охватывает диапазон ячеек B2:D7, искомое_значение должно находиться в столбце B.
Искомое_значение может являться значением или ссылкой на ячейку.
таблица (обязательный)
Диапазон ячеек, в котором будет выполнен поиск искомого_значения и возвращаемого значения с помощью функции ВПР. Вы можете использовать именованный диапазон или таблицу, а также имена в аргументе вместо ссылок на ячейки.
Первый столбец в диапазоне ячеек должен содержать искомое_значение. Диапазон ячеек также должен содержать возвращаемое значение, которое нужно найти.
номер_столбца (обязательный)
Номер столбца (начиная с 1 для крайнего левого столбца таблицы), содержащий возвращаемое значение.
интервальный_просмотр (необязательный)
Логическое значение, определяющее, какое совпадение должна найти функция ВПР, — приблизительное или точное.
- Вариант Приблизительное совпадение — 1/ИСТИНА предполагает, что первый столбец в таблице отсортирован в алфавитном порядке или по номерам, а затем выполняет поиск ближайшего значения. Это способ по умолчанию, если не указан другой. Например, =ВПР(90;A1:B100;2;ЛОЖЬ).
- Вариант Точное совпадение — 0/ЛОЖЬ осуществляет поиск точного значения в первом столбце. Например, =ВПР(«Иванов»;A1:B100;2;ЛОЖЬ).
Начало работы
Для построения синтаксиса функции ВПР вам потребуется следующая информация:
- Значение, которое вам нужно найти, то есть искомое значение.
- Диапазон, в котором находится искомое значение. Помните, что для правильной работы функции ВПР искомое значение всегда должно находиться в первом столбце диапазона. Например, если искомое значение находится в ячейке C2, диапазон должен начинаться с C.
- Номер столбца в диапазоне, содержащий возвращаемое значение. Например, если в качестве диапазона вы указываете B2:D11, следует считать B первым столбцом, C — вторым и т. д.
- При желании вы можете указать слово ИСТИНА, если вам достаточно приблизительного совпадения, или слово ЛОЖЬ, если вам требуется точное совпадение возвращаемого значения. Если вы ничего не указываете, по умолчанию всегда подразумевается вариант ИСТИНА, то есть приблизительное совпадение.
Теперь объедините все перечисленное выше аргументы следующим образом:
=ВПР(искомое значение; диапазон с искомым значением; номер столбца в диапазоне с возвращаемым значением; приблизительное совпадение (ИСТИНА) или точное совпадение (ЛОЖЬ)).
Примеры
Вот несколько примеров использования функции ВПР.
Пример 1
Пример 2
Пример 3
Пример 4
Пример 5
Объединение данных из нескольких таблиц на одном листе с помощью функции ВПР
С помощью функции ВПР вы можете объединить несколько таблиц в одну, если одна из таблиц содержит поля, общие для всех остальных. Это может быть особенно удобно, если вам нужно поделиться книгой с пользователями более старых версий Excel, которые не поддерживают функции данных с несколькими таблицами в качестве источников данных. Благодаря объединению источников в одну таблицу и изменению источника функции данных на новую таблицу, функцию данных можно использовать в более старых версиях Excel (при условии, что функция данных поддерживается в более старой версии).
Здесь столбцы A–F и H содержат значения или формулы, которые используют значения только на этом листе, а в остальных столбцах используется функция ВПР и значения столбца А (код клиента) и столбца B (адвокат) для получения данных из других таблиц.
- Скопируйте таблицу с общими полями на новый лист и присвойте имя.
- Щелкните Данные >Работа с данными >Отношения, чтобы открыть диалоговое окно «Управление отношениями».
- Для каждого отношения в списке обратите внимание на следующее.
- Поле, которое связывает таблицы (указано в скобках в диалоговом окне). Это искомое_значение для вашей формулы ВПР.
- Имя связанной таблицы подстановки. Это таблица в вашей формуле ВПР.
- Поле (столбец) в связанной таблице подстановки, содержащее данные, которые вам нужны в новом столбце. Эта информация не отображается в диалоговом окне «Управление отношениями». Чтобы увидеть, какое поле нужно получить, посмотрите на связанную таблицу подстановки. Обратите внимание на номер столбца (A=1) — это номер_столбца в вашей формуле.
- Чтобы добавить поле в новую таблицу, введите формулу ВПР в первом пустом столбце, используя сведения, собранные на шаге 3. В нашем примере столбец G использует адвоката (искомое_значение) для получения данных ставки из четвертого столбца (номер_столбца = 4) из таблицы листа «Адвокаты», тблАдвокаты (таблица), с помощью формулы =ВПР([@Адвокат];тбл_Адвокаты;4;ЛОЖЬ). Формула также может использовать ссылку на ячейку и ссылку на диапазон. В нашем примере это =ВПР(A2;’Адвокаты’!A:D;4;ЛОЖЬ).
- Продолжайте добавлять поля, пока не получите все необходимые поля. Если вы хотите подготовить книгу, содержащую функции данных, которые используют несколько таблиц, измените источник данных для функции данных на новую таблицу.
Линейный алгоритм. Понятие и особенности. Блок-схема
Каждый человек на протяжении своей жизни решает множество задач разной сложности. Но даже самые простые из задач выполняются последовательно, то есть за несколько шагов. Эту последовательность можно назвать алгоритмом. Последовательности бывают разные, но начинать их изучение лучше всего с линейных.
Прежде чем приступить к рассмотрению основной темы статьи, следует сделать краткое отступление и сказать несколько слов про алгоритмический язык.
Алгоритмический язык
Представьте, что человеку, работающему за компьютером, поставлена некая вычислительная задача. В языке программирования решение этой задачи выполняется с помощью алгоритмизации. Решение предполагает: — разбиение на этапы; — разработку алгоритма; — составление программы решения на алгоритмическом языке; — ввод данных; — отладку программы (возможны ошибки — их надо исправить); — выполнение на ПК; — анализ результатов.
Алгоритмический язык является средством описания алгоритмов, а уже алгоритм, в свою очередь, представляет собой чёткое описание определённой последовательности действий, направленных на решение необходимой задачи.
Свойства алгоритма
Их несколько: — конечность. Любой алгоритм должен быть завершённым, а окончание наступает после выполнения определённого числа шагов; — однозначность, понятность. Не допускается разных толкований, неопределённости и двусмысленности — всё должно быть чётко и ясно, а также понятно исполнителю — и правила выполнения действий линейного алгоритма, и сами действия; — результативность. Итог работы — результат, полученный за конечное число шагов; — универсальность, массовость. Качественный алгоритм способен решать не одну задачу, а целый класс задач, имеющих схожую постановку/структуру.
Линейная структура
Любой алгоритм составляется из ряда базовых структур. Простейшей базовой структурой является следование — структура с линейными характеристиками. Из этого можно сформулировать определение.
Линейный алгоритм — это алгоритм, образуемый командами, которые выполняются однократно и именно в той последовательности, в которой записаны. Линейная структура, по сути, проста. Записать её можно как в текстовой, так и в графической форме.
Представим, что у нас стоит задача пропылесосить ковёр в комнате. В текстовой форме алгоритм будет следующим: — принести пылесос к месту уборки; — включить; — пропылесосить; — выключить; — унести пылесос.
И каждый раз, когда нам надо будет пылесосить, мы будем выполнять один и тот же алгоритм.
Теперь поговорим про графическую форму представления.
Блок-схема
Для изображения алгоритма графически используют блок-схемы. Они представляют собой геометрические фигуры (блоки), соединённые стрелками. Стрелки показывают связь между этапами и последовательность их выполнения. Каждый блок сопровождается надписью.
Рассмотрим фигуры, которые используются при визуализации типичной линейной последовательности.
Блок ввода-вывода данных (отображает список вводимых и выводимых переменных):
Арифметический блок (отображает арифметическую операцию/группу операций):
Условный блок (позволяет описать условие). Алгоритмы с таким блоком используются при графической визуализации алгоритмов с ветвлением:
Условного блока нет в классическом линейном алгоритме, так как в нём, как уже было сказано ранее, все операции выполняются последовательно, то есть одна за другой. В линейном алгоритме размещение блоков выглядит следующим образом:
А вот, как решается задача по нахождению площади треугольника по формуле Герона. Здесь a, b, c – это длины сторон, S – площадь треугольника, P – периметр.
Следует обратить внимание, что запись «=» — это не математическое равенство, а операция присваивания. В результате этой операции переменная, стоящая слева от оператора, получает значение, которое указано справа. Значение не обязательно должно быть сразу определено (a = 3) — оно может вычисляться посредством выражения (a = b + z), где b = 1, a z = 2.
Примеры линейных алгоритмов
Если рассмотреть примеры решения на языке Pascal (именно этот язык до сих пор используется для изучения основ алгоритмизации и программирования), то можно увидеть следующую картину:
И, соответственно, блок-схема программы линейной структуры будет выглядеть следующим образом:
Как составить программу линейной структуры?
Порядок следующий: — определите, что именно относится к исходным данными, а также каков типы/класс этих данных, выберите имена переменных; — определите, каков тип данных будет у искомого результата, выберите название переменных (переменной); — определите, какие математические формулы связывают результат и исходные данные; — если требуется наличие промежуточных данных, определите класс/типы этих данных и выберите имена; — опишите все используемые переменные; — запишите окончательный алгоритм. Он должен включать в себя ввод данных, вычисления, вывод результатов.
На этом всё, в следующий раз рассмотрим на примерах программу разветвлённой структуры. Если же вас интересует тема алгоритмизации в контексте разработки программного обеспечения, ждём вас на профессиональном курсе OTUS!
Для ячейки, связанной с текстовым форматом, отображается значение «не является значением»
В Microsoft Excel при вводе формулы, которая связывает одну ячейку с текстовым форматом, ячейка, содержащая ссылку, также форматируется как текст. Если затем изменить формулу в связанной ячейке, в ячейке будет отображена формула, а не значение, возвращаемое формулой.
Причина
При связывании ячеек в Microsoft Excel к связанной ячейке применяется формат исходной ячейки. Таким образом, при вводе формулы, которая связывает одну ячейку с ячейкой, которая форматируется как текст, ячейка с формулой также форматируется как текст.
Обходное решение
Чтобы отобразить вычисляемое значение, а не формулу, необходимо изменить формат ячейки, содержащей формулу, и ввести формулу повторно. Для этого выполните следующие действия:
- Выделите ячейку с формулой, а затем в меню Формат выберите пункт ячейки.
- Откройте вкладку число. Выберите код формата, который будет отображаться в ячейке, и нажмите кнопку ОК. В ячейке по-прежнему отображается формула.
- Выделите ячейку с формулой, нажмите клавишу F2, а затем нажмите клавишу ВВОД. В ячейке отображается значение.
- В той же ячейке в меню Формат выберите пункт ячейки. Категория формат ячейки будет представлять собой текст.
- Укажите категорию и параметры форматирования для ячейки, а затем нажмите кнопку ОК.
Теоретический материал: файловый ввод-вывод (Паскаль)
Файлы. Виды файлов. Основные процедуры для работы с файлами
До сих пор мы рассматривали задачи, в которых во время выполнения программы данные поступают с клавиатуры, а результаты выводятся на экран дисплея. При этом ни исходные данные, ни результаты не сохраняются. Всякий раз при выполнении одной и той же программы, в частности, во время отладки, приходится заново вводить данные. А если их очень много? В языке Паскаль есть возможность записать их на диск. Для этого необходимо оформить исходные данные и результаты в виде файлов, которые хранятся на диске точно так же, как и программы.
Понятие файла — это фундаментальное понятие информатики, вспомним же его определение.
Определение. Файлом называется область памяти на диске, имеющая свое имя.
Вы знаете различные виды физических файлов: системные, графические, текстовые и другие, зачастую созданные той или иной прикладной программой. И любой из этих физических файлов Вы сможете считать, проанализировать, изменить и записать.
Физические файлы можно по-разному представить в программе. Язык Турбо Паскаль предлагает три вида представления файлов:
И Вы, в зависимости от решаемой задачи, вольны выбирать один их трех видов, а, может быть, и несколько. Для того, чтобы сделать правильный выбор, Вы должны хорошо знать не только процедуры и функции, являющиеся общими для всех видов файлов, но и специфичные для каждого вида.
Для работы с конкретным физическим файлом на диске надо представить в программе так называемую файловую переменную и произвести ее логическую связку с этим файлом. Файловые переменные имеют специфическое применение. Над ними нельзя выполнять никаких операций (присваивать значение, сравнивать и др.). Их можно использовать только для выполнения операций с файлами (чтения, записи, удаления файла и т.д.). Кроме того, через файловую переменную можно получить информацию о конкретном файле (тип, параметры, имя файла и т.д.).
По сути, любой физический файл можно представить как последовательность блоков информации некоторого типа. Все компоненты файла имеют общее имя, а каждый имеет еще и свой номер. Начальный элемент имеет нулевой номер.
Количество элементов файла может быть любым: число компонентов файла может изменяться (увеличиваться или уменьшаться), то есть, заранее не фиксируется. В файлах можно хранить достаточно большое количество данных. После каждого элемента файла автоматически ставится признак конца элемента, а в конце файла ставится признак конца файла.
С каждым файлом можно связать понятие «текущий указатель». Это неявно описанная переменная, которая указывает на конкретный элемент файла. Действия с файлами производятся поэлементно, причем в них участвует тот элемент, на который «смотрит» текущий указатель, перемещающийся в результате выполнения действия на следующий элемент.
Главное, чему необходимо научиться при работе с файлами — это записать информацию из программы в файл и считать нужную информацию в выделенную переменную для обработки программой. Общая последовательность действий при этом такова:
— описать переменную файлового типа;
— связать ее с конкретным физическим файлом процедурой assign;
— открыть файл процедурой reset или rewrite;
— выполнить чтение или запись информации;
— по окончании работы с файлом закрыть файл процедурой close.
Формат объявления файловых переменных и особенности работы с различными видами файлов (типизированными, нетипизированными, текстовыми) будут подробно изложены далее.
Процедуры и функции для работы с файлами любого типа
Переменные файлового типа используются в программе только в качестве параметров собственных и стандартных процедур и функций. Все фактические действия с файлами основаны на наборе стандартных процедур языка, входящих в состав модулей System и Dos.
Сначала рассмотрим процедуры модуля System.
Напомним, что он подключен к программам по умолчанию, то есть его не требуется подключать к программе в разделе Uses.
До начала работы с файлами устанавливается связь файловой переменной МуFilе с именем дискового файла. Очень важно различать собственно файл (область памяти на магнитном носителе с некоторой информацией) и переменную файлового типа в Turbo Pascal-программе. Считается, что файловая переменная является представителем некоторого дискового файла в программе. Для того, чтобы реализовать доступ к файлу на магнитном диске, программа должна связать его с файловой переменной. Для этого необходимо установить соответствие между переменной и именем файла. Это имя представляется в виде строки, содержащей имя файла и, может быть, путь к файлу, который формируется по общим правилам MS-DOS.
assign (МуFilе, ‘с:\МуDirectory\Result.dat’); |
здесь приведено полное (с указанием пути) имя пользовательского файла Result.dat.
Если путь не указан, программа будет искать файл только в своем рабочем каталоге и, как это принято в системе DOS, по указанным в файле аutoехес.bat путям. Кроме указания имени файла на дисковом накопителе может быть указано стандартное имя одного из устройств ввода-вывода: «соn» — консоль, то есть дисплей и клавиатура, «рrn» — или «lpt1» — принтер.
Не разрешается связывать с одним физическим файлом разные файловые переменные программы.
До тех пор, пока файловая переменная не связана с каким-либо дисковым файлом, никакие операции с ней в программе невозможны. Заметим, что можно связать файловую переменную с еще не существующим дисковым файлом. Это делается в случае последующего создания Turbo Pascal-программой файла с данным именем с помощью специальной системной процедуры.
После того, как файловая переменная с помощью процедуры Аssign связана с конкретным дисковым файлом, с ним можно выполнить любую допустимую операцию.
Внимание! Нельзя применять процедуру assign к открытому файлу.
Все файлы, открытые в результате работы программы, должны быть закрыты при завершении программы процедурой
closе (МуFilе); |
При выполнении этого оператора закрывается физический файл на диске, и фиксируются изменения, связанные с использованием данного файла. Обратите внимание на необходимость закрытия файлов во всех ветвях программы, в том числе в различных аварийных ситуациях. Незакрытые файлы нарушают файловую структуру на диске, что может приводить к серьезным проблемам с настройкой компьютера.
Открытие нового файла производится процедурой, единственный аргумент которой — переменная файлового типа, например:
rewrite (МуFilе); |
Эта процедура создает на диске файл с именем, связанным с переменной МуFilе процедурой Аssign. Указатель работы с файлом устанавливается на начало файла. После выполнения процедуры rewrite файл доступен как для записи, так и для чтения (в случае текстовых файлов – только для записи).
Внимание! Если файл с таким именем уже существует, он удаляется (его содержимое теряется), и создается новый пустой файл с данным именем.
Открытие существующего файла выполняет процедура
reset (МуFilе); |
Эта процедура ищет уже существующий файл на диске и открывает его для работы, помещая указатель в начальную позицию. Если файл с установленным в Аssign именем не найден, возникает ошибка ввода/вывода, контроль которой зависит от директивы компилятора (смотрите здесь). После выполнения процедуры reset файл доступен как для записи, так и для чтения (в случае текстовых файлов – только для чтения).
Запись в файл производится процедурой
write (МуFilе, var1, var2, . varN); |
Первый аргумент этой процедуры — переменная файлового типа, далее следует список записываемых переменных, которые должны соответствовать объявленному типу файла. При выполнении этой операции текущий указатель файла смещается на число позиций, равное числу переменных.
Чтение из файла производится аналогичной процедурой:
read (МуFilе, var1, var2, . varN); |
Примечание. Особенности выполнения операций записи и чтения для нетипизированных и текстовых файлов описаны в соответствующих разделах.
Положение элементов в файле нумеруется, начиная с номера 0 для первого элемента. После последнего элемента файла автоматически записывается признак конца файла.
Функция FileSize(МуFilе) определяет число элементов в файле. Функция неприменима к текстовым файлам. Файл MyFyle должен быть открыт.
Функция логического типа ЕОF(МуFilе) имеет значение Тruе, если указатель указывает на маркер конца файла (End Of File).
Типизированные файлы
Определение. Типизированный файл — последовательность элементов одного типа. Таким образом, типизированный файл Вы можете представить себе как цепочку однотипных данных. Все компоненты файла имеют общее имя, а каждый – еще и свой номер. Начальный элемент имеет нулевой номер. Длина файла, то есть количество элементов в цепочке — величина произвольная, изменяемая в процессе работы. После последнего элемента автоматически записывается признак конца файла. Описание файлового типа для работы с типизированным файлом имеет синтаксис:
Допустим, мы имеем дело с файлом, в котором записываются переменные типа Word, тогда переменная файлового типа может быть введена двояко – с явным объявлением файлового типа:
Type WordFile = file of word; Var MyFile : WordFile; |
или без объявления файлового типа:
Var MyFile : file of word; |
Приведем примеры переменных файлового типа с другими объявлениями:
Type Student = record Name, SurName : string; YearsOld : byte; Sessia : array [1..10] of byte; end; Var VarFile1 : file of char; VarFile2 : file of Student; VarFile3 : file of string; |
Напомним, что файловые переменные имеют специфическое применение: их можно использовать только для выполнения операций с файлами (чтения, записи, удаления файла и т.д.) и получения информации о конкретном файле (тип, параметры, имя файла и т.д.). Работа с файлами заключается в записи и считывании его компонентов. Для того, чтобы определить, какие данные будут участвовать в операции, используется неявно заданная переменная – указатель на текущий элемент файла. При открытии файла процедурами reset, rewrite указатель устанавливается на его начало. Запись и чтение производятся поэлементно, причем в них участвует тот элемент файла, на который «смотрит» указатель. В результате выполнения действия указатель перемещается к следующему элементу. Пример. Приведем шаблон программы для записи данных в типизированный файл.
Program Writing; Var FileName : string; FVar : file of byte; Index : byte; Begin write (‘Введите имя файла ‘); readln (FileName); assign (FVar, FileName); rewrite (FVar); for Index := 0 to 99 do write (FVar,Index); close (FVar); End. |
Примечание. В цикле могут быть вычислительные процедуры для получения данных, выводимых в файл. Мы, для простоты, записали в файл счетчик цикла. Внимание! Следует запомнить, что процедура rewrite очистит файл, если файл с таким именем уже есть в рабочем каталоге, поэтому при выборе имен файлов соблюдайте осторожность. Задание 1. Наберите предложенную выше программу и дополните ее выводом на экран элементов файла (воспользуйтесь процедурой считывания из файла read и вывода на экран write). Задание 2. Создайте программу записи и чтения типизированного файла типа string.
Примеры решения задач
Рассмотрите примеры решения задач. Наберите тексты программ, проверьте их. Обратите внимание на комментарий. Выполните задания к задачам. Задача 1. Дан файл, элементами которого являются целые числа. Найти среднее арифметическое элементов файла. В примере выполняется считывание элементов из файла, их суммирование и нахождение среднего арифметического. Предполагается, что типизированный файл уже создан. Задание. Дополните программу созданием типизированного файла file.dat. Добавленные строчки программы прокомментируйте.
Program Srednee; Uses Crt; Var Kol, Element, Summa :integer; f : file of integer; SrAriph : real; Begin ClrScr; assign(f,’file.dat’); reset(f); Summa :=0; Kol :=0; while not Eof(f) do begin read(f, Element); Inc(Kol); Inc(Summa, Element); end; if Kol > 0 then begin     SrAriph := Summa/Kol;     write(‘Среднее арифметическое элементов файла равно ‘, SrAriph:5:2); end else     write(‘Файл пуст’); close(f); readln; End. |
Задача 2. Наберите на компьютере и проанализируйте текст программы, сформулируйте решаемую в ней задачу, дополните необходимыми операторами и комментарием.
Program FileString; Uses Crt; Var f, g : file of string; str1, str : string; i : integer; Begin ClrScr; Str1 := »; assign(f,’f’); rewrite(f); assign(g,’g’); rewrite(g); repeat readln(str); write(f,str); for i:=length(str) downto 1 do str1:=str1+str[i]; write(g,str1); str1:=»; until str=»; close(f); close(g); assign(f,’f’); reset(f); assign(g,’g’); reset(g); while not eof(f) do begin read(f,str); writeln(str); end; while not eof(g) do begin read(g,str); writeln(str); end; close(f); close(g); readln; End. |
- нахождением среднего стажа работы в институте;
Program TipRecord; Uses Crt; Type Dann=record stag : byte; Surname, WorkName : string; Oklad, Year : integer; End; Var Spisok : file of Dann; Man : Dann; Name : string[12]; Procedure VvodZap (Nomer : integer); Begin with Man do begin writeln(‘Введите данные ‘,Nomer,’-го работника’); write(‘Фамилия: ‘); readln(Surname); write(‘Год рождения: ‘); readln(Year); write(‘Стаж работы: ‘); readln(stag); write(‘Должность: ‘); readln(WorkName); write(‘Оклад: ‘); readln(oklad); write(Spisok, Man); end; End; Procedure FileVvod; Var i, count : Integer; Begin write(‘Введите имя файла данных:’); readln(Name); assign(Spisok, Name); rewrite(Spisok ); write(‘Введите количество работников:’); readln(count); for i:=1 to count do VvodZap(i); close(Spisok); readln; End; Begin ClrScr; FileVvod; readLn; End. |
Процедуры и функции для работы с типизированными файлами
Вспомним, что типизированный файл — это линейная последовательность элементов одного типа. При каждом обращении к файлу (чтении, записи) его текущий указатель перемещается к следующему элементу. Возникает вопрос: можно ли нарушить порядок доступа к элементам файла и, например, не считывая из файла первый и второй элемент, сразу обратиться к третьему? Оказывается, можно.
Для изменения теущего положения указателя используется процедура
Seek (МуFilе, n); |
где n — требуемое положение указателя.
Внимание! Нумерация элементов типизированного файла начинается с нуля.
Следовательно, для обращения к третьему элементу нужно записать: Seek (МуFilе, 2).
Seek (МуFilе, 0) — устанавливает указатель в начальную позицию (на первый элемент).
Seek (МуFilе, FileSize(МуFilе)) — устанавливает указатель после последнего элемента, то есть на признак конца файла.
Примечание. Функция FileSize(МуFilе) возвращает количество элементов типизированного файла МуFilе.
Текущую позицию указателя дает функция
FilePos (МуFilе); |
Задача. Составить программу, которая переписывает существующий файл, заменяя все латинские буквы на заглавные.
Рrogram Writing; Var FileName : string; FVar : file of char; Index : integer; Letter : char; Begin write(‘Enter filename: ‘); readln (FileName); assign (FVar,FileName); reset (FVar); if IOResult <> 0 |
Функция IOResult
Как Вы уже заметили, в предыдущей программе была использована функция IOResult. Рассмотрим, какую роль выполняет эта функция.
Функция IOResult позволяет программисту самостоятельно обработать ошибки, возникающие при работе с файлами, избжав тем самым автоматического завершения программы с выдачей непонятного пользователю аварийного сообщения.
Если контроль за выполнением операций ввода/вывода отключен с помощью директивы компилятора , функция возвращает признак наличия ошибки в процессе выполнения последней операции ввода/вывода. При успешном завершении проверяемой операции возвращаемое функцией IOResult значение равно нулю.
Используя функцию IOResult, нужно помнить о том, что она должна вызываться сразу вслед за проверяемой операцией. Если же Вы хотите провести анализ ошибки позже, Вам придется сохранить возвращаемое функцией значение в некоторой промежуточной переменной.
Просмотрите еще раз фрагмент программы, в которой посредством процедуры reset производится попытка открытия файла. Если эта попытка не увенчалась успехом, то на экран будет выведено сообщение об ошибке.
reset (F,’C:\TP7\BIN\Text.txt’); if IOResult <> 0 then writeln (‘Ошибка при открытии файла’); |
В своих программах Вы должны применять функцию IOResult.
Замечание. Функция применима к операциям файлового ввода/вывода независимо от вида файла (типизированный, нетипизированный, текстовый).
Решение задач
Задание. Рассмотрите предложенный ниже текст программы. Сформулируйте решаемую задачу.
Program Files; Uses Crt; Var F, Fnew : file of string; Name, NewName : string[12]; Str : string; Ch : char; Procedure ReadText; Begin repeat write(‘Введите имя файла>’); readln(Name); assign(F, Name); reset(F); if IOresult<>0 then begin writeln(‘Ошибка чтения’); close(F); end; until IOresult=0; writeln(‘Содержание файла ‘, Name,’:’); while not Eof(F) do begin read(F, Str); writeln(Str); end; close(F); End; Procedure EraseFile; Begin erase(F); writeln(‘Файл удален’); End; Procedure ReNameFile; Begin write(‘Введите новое имя файла:’); readln(NewName); rename(F, NewName); writeln(‘Файл ‘, Name,’ переименован в файл ‘, NewName); End; Procedure CopyFile; Begin write(‘Введите имя копии файла ‘, Name,’>’); readln(NewName); reset(F); assign(Fnew, NewName); rewrite(Fnew); while not Eof(f) do begin read(F, Str); write(Fnew, Str); end; close(F); close(Fnew); writeln(‘Файл’, Name,’ скопирован в файл ‘, NewName); End; Begin ClrScr; readTеxt; repeat writeln(‘Удаление файла (D),переименование файла(R)’); writeln(‘Копирование файла (C), выход из программы (Е)’); write(‘Введите символ нужной операции — ‘); readln(ch); case ch of ‘D’,’d’: EraseFile; ‘R’,’r’: ReNameFile; ‘C’,’c’: CopyFile; end; until (ch=’E’) or (ch=’e’); readln; End. |
Тeкстовые файлы, их описание и основные отличия от типизированных файлов
Наряду с типизированными файлами Pascal имеет средства взаимодействия с файлами несколько иной структуры — так называемыми текстовыми файлами. Введение текстовых файлов несколько нарушает стройность языка, однако позволяет использовать Pascal при программировании широкого класса задач, имеющих нечисловой характер и связанных с обработкой текстовой информации. Во многих версиях языка допускается хранение файлов на диске как символьных данных. При считывании файла в оперативную память машины символы файла преобразуются в тот тип данных, который объявлен в программе. Файлы символьных данных называются текстовыми файлами. Структура текстовых файлов отличается от структуры обычных файлов (которые представляют собой линейную последовательность элементов одного типа) тем, что содержимое текстового файла рассматривается как последовательность строк переменной длины, разделённых специальной комбинацией кодов, называемой «конец строки». Как правило, эта комбинация строится из управляющего кода «возврата каретки» (CR, Carriage Return, символ #13), за которым, возможно, следует управляющий код «перевод строки» (LF, Line Feed, символ #10). При вводе c клавиатуры признаком конца строки считается нажатие клавиши Enter. Текстовый файл завершается специальным кодом «конец файла» (символ #26). В большинстве случаев знание конкретной кодировки управляющих символов не обязательно ввиду наличия файловых операций, автоматически учитывающих эти символы. Таким образом, текстовый файл структурно несколько похож на «файл из байтов» (file of byte) с той разницей, что в нем, помимо содержательной информации, встречаются символы специального назначения. Его можно схематически представить в следующем виде: . . . . . . . . . . . . . .#13#10
. . . . . . . . . . . . . . . . . . . .#13#10
. . . . . . . . . . . . . . . . .#13#10
. . . . . . . . . . . .#13#10
. . . . . . . . . . . . . . . . . . . . . . . . . .#13#10
#26 Описанная структура текстовых файлов хорошо согласуется с интуитивно понятным построением текстовой информации и полностью совпадает со стандартной структурой текстов, используемой во многих текстовых редакторах, понимаемой компиляторами с языков программирования и т.д. С каждым файлом на диске в программе должна быть связана некоторая файловая переменная, которая описывается в соответствии с типом файла. Текстовому файлу в Pascal-программе соответствует переменная, которая должна быть описана с указанием стандартного типа text:
Var TextFile : text; |
Примечание. Слово text не является зарезервированным словом, а считается идентификатором стандартного типа, наряду с идентификаторами integer, real и т.д. После описания переменной типа text ее надо связать с конкретным файлом процедурой assign. Вся последующая работа с файлом будет вестись через файловую переменную. Далее доступ к файлу требуется открыть на чтение или на запись, для этого существуют процедуры reset и rewrite. К примеру, пусть на диске создан текстовый файл text.txt. Для Turbo Pascal описание и связывание файловой переменной f с файлом text.txt, будет выглядеть так :
Var f: text; Begin assign(f, ‘d:\tp7\bin\text.txt’); reset(f); . . . End. |
Процедура assign( , ) — связывает файл на диске с файловой переменной типа Text. Примечание. Процедура assign не должна использоваться для открытого файла. Если при вызове процедуры assign в качестве имени файла задается пустая строка: assign(f,»), то после обращения к reset(f) переменная f будет связана со стандартным файлом ввода, а после обращения к rewrite(f) – со стандартным файлом вывода. Процедура reset( ) — открывает файл на чтение. Ввод-вывод для текстовых файлов подчиняется тем же правилам, что и для типизированных файлов; однако имеется несколько важных особенностей. Во-первых, для одного текстового файла нельзя одновременно производить операции и ввода, и вывода. Это означает, что после открытия текстового файла процедурой reset возможно только чтение информации из файла, а после процедуры rewrite — только запись в файл. Во-вторых, обмены с текстовыми файлами всегда являются строго последовательными, то есть после чтения из файла элемента с порядковым номером N следующая операция чтения даст элемент с номером N+1. Иными словами, прямой доступ к любому элементу текстового файла невозможен; для текстовых файлов не допускаются вызовы Seek, FilePos, FileSize. Под чтением файла понимают ввод данных из внешнего файла, находящегося на диске, в оперативную память компьютера. Данные файла становятся доступными программе. Внешний файл, из которого читаются данные, часто называют входным файлом. Базовой техникой обменов с текстовыми файлами является посимвольный ввод-вывод. При этом производится чтение или запись всех символов, как информационных, так и специальных. Покажем простую программу, выполняющую чтение некоторого текста. Эта программа выводит на экран последовательность кодов символов, составляющих файл text.txt.
Program TextFile1; Var f : text; S : char; Begin assign(f, ‘text.txt’); reset(f); while not Eof(f) do begin read(f, S); writeln(S:2, ord(S):4); end; close(f); readln End. |
Задание. Наберите текст программы и запустите программу на выполнение. Просмотрите результат работы программы. Найдите выведенные на экран коды специальных символов. Еще одной особенностью работы с текстовыми файлами является возможность чтения из файла (записи в файл) значений различных базовых типов, тогда как для типизированных файлов тип параметров процедур read и write всегда должен совпадать с базовым типом файла. Например, в текстовый файл можно записать целое или вещественное число, при этом его внутреннее представление будет автоматически преобразовано в строчку символов, образующих изображение этого числа. Рассмотрите простую программу, выполняющую чтение из текстового файла целых чисел и вывод на печать только четных чисел.
Program TextFile2; Var f : text; Put : string; a : integer; Begin Put := ‘D:\TP7\BIN\Primer2’; assign(f, Put); reset(f); while not Eof(f) do begin readln(f, a); if not odd(a) then writeln(a); end; close(f); readln End. |
- значения целого типа;
- значения вещественного типа;
- значения булевского типа.
Для записи произвольной информации в текстовый файл в языке имеются дополнительные возможности, которые заключаются в задании размера поля записи. Если после записываемой переменной или выражения поместить символ двоеточия, а после него — любое выражение целого типа, то для выводимого значения будет отведено поле, размер которого (число символов) будет равен значению выражения. Следующая тривиальная программа наглядно показывает действие указателя поля:
Program TextFile3; Var f : text; V : real; i : word; Put : string; Begin Put := ‘D:\TP7\BIN\Primer3’; assign(f, Put); rewrite(f); V := 123.456; write(f, V,#13#10); for i := 10 to 14 do write(f, V:i,#13#10); close(f); End. |
Задание. Наберите программу, дополните ее выводом содержимого текстового файла на экран. Проанализируйте результаты выполнения программы.
Управление размещением значений в текстовых файлах очень удобно использовать при формировании структурированных файлов (списков, таблиц и т.п.). Если количество позиций, занимаемых выводимым значением меньше размера поля, то значение всегда «прижимается» к правому краю поля.
Для вещественных типов имеется дополнительная возможность, позволяющая выводить число в формате с фиксированной точкой, что более наглядно по сравнению с форматом с плавающей точкой, который предусмотрен по умолчанию. Если после указателя размера поля задать через двоеточие еще одно выражение целого типа, то оно будет интерпретироваться как указание числа позиций для дробной части числа.
Способы обмена с текстовыми файлами
На этом занятии мы обобщим уже известные нам сведения о работе с текстовыми файлами и остановимся на особенностях обмена информацией между программой и текстовым файлом.
Операции чтения из файла
reset(f) — открывает существующий файл на чтение. Файловая переменная должна быть связана с внешним файлом с помощью процедуры assign.
Если существующий файл уже открыт, то он закрывается, а затем открывается вновь. Текущая позиция в файле устанавливается на начало файла.
Если f соответствует пустое имя файла (например, после вызова assign(f, »)), то после обращения к процедуре Reset(f) будет использоваться стандартный файл ввода (канал 0).
Текстовый файл становится доступным только на чтение.
При указании директивы компилятора функция IoResult будет возвращать значение 0 в том случае, если операция завершилась успешно, и ненулевой код ошибки в противном случае.
read( [f : text], v1 [, v2, . vn] ) — читает из текстового файла значения одной или более переменных.
Если параметр f не указан, то подразумевается использование стандартной файловой переменной Input. Каждый параметр v является переменной, значение которой должно быть прочитано из файла.
readln( [f : text], [v1, v2, . vn] ) — выполняет процедуру read, затем переходит к следующей строке файла.
Процедура readln является расширением процедуры read и определена для текстовых файлов. Вызов readln(f) с указанием одного параметра-файловой переменной приводит к перемещению текущей позиции файла на начало следующей строки, если она имеется, в противном случае происходит переход к концу файла. Процедура readln без параметров полностью соответствует стандартному вводу.
При указании директивы компилятора функция IoResult будет возвращать значение 0 в том случае, если операция завершилась успешно, и ненулевой код ошибки в противном случае.
Примечание: Процедура работает только для текстовых файлов, включая стандартный ввод. Файл должен быть открыт для ввода.
Процедура readln является очень удобным аналогом read. В случае использования readln после чтения из файла очередной порции символов (и, быть может, преобразования их в значение подходящего типа) текущий указатель файла будет перемещен на начало его следующей строки. Иными словами, остаток строки, расположенный в файле после прочитанного значения, будет пропущен.
Очень часто используется следующий способ чтения из текстового файла. В качестве параметра процедуры readln задается переменная типа string; в этом случае вся очередная строка файла целиком считывается в данную переменную, длина которой автоматически устанавливается равной длине считанной строки. Полученная из файла строка далее может быть обработана так, как это необходимо. Важно отметить, что при таком способе производится чтение только «значащих» символов строки; завершающиеся символы в данном случае играют роль межстрочных разделителей и не считываются в строковую переменную. После чтения строки текущий указатель файла устанавливается на начало следующей строки.
Операции записи в файл
rewrite(f) — cоздаёт и открывает новый файл. Файловая переменная должна быть связана с внешним файлом с помощью процедуры assign.
Если внешний файл уже существует, то он удаляется, и на его месте создаётся новый пустой файл. Если файл уже открыт, то он закрывается, а затем открывается вновь. Текущая позиция в файле устанавливается на начало файла.
Если f соответствует пустое имя файла (например, после вызова assign(f, »)), то после обращения к процедуре rewrite(f) будет использоваться стандартный файл вывода (канал 1).
Текстовый файл становится доступным только на запись.
write( [f : text], v1 [, v2, . vn] ) — записывает значения одной или более переменных в текстовый файл.
Если параметр f не указан, то подразумевается использование стандартной файловой переменной Output. Каждый параметр v является выражением, значение которого должно быть записано в файл. Выводимое выражение должно быть символьного, целого, вещественного, строкового или булевского типа.
Параметр v может иметь вид:
Var a:real; . . . . . . . write(f, a: 5: 2); |
Такая запись означает, что мы в файл записываем действительное (не целое) число а, размером 5 знаков, 2 знака под дробную часть.
writeln( [f : text], [v1, v2, . vn] ) — выполняет процедуру write, а затем записывает в файл метку конца строки (перевод строки).
При вызове данной процедуры с указанием только параметра-файловой переменной: writeln(f), в файл записывается метка конца строки. Процедура writeln без параметров полностью соответствует стандартному выводу на экран.
Примечание. Процедура работает только для текстовых файлов, включая стандартный вывод. Файл должен быть открыт для вывода.
Логическая функция Eoln
Часто для обработки текстовых файлов используется специфичная для них функция Eoln, позволяющая определить, достигнут ли конец строки. Если достигнут — значение функции равно True, а если нет — False. Таким образом, для анализа конкретных символов строк файла можно применить вложенный цикл типа:
while not Eof(FileName) do while not Eoln(FileName) do begin end; |
Процедура открытия файла для дополнения
append(f : Тext) — процедура открывает существующий файл для дозаписи. Если файл уже открыт, то он сначала закрывается, а затем открывается заново. Текущая позиция устанавливается на конец файла.
Если в последнем блоке файла размером 128 байтов присутствует символ Сtrl+Z (26 в коде ASCII), то текущая позиция устанавливается в файле таким образом, что при записи первым в блоке будет «затираться» символ Сtrl+Z.
Если переменной f соответствует пустое имя файла (например, после вызова assign(f, »)), то после обращения к процедуре append переменная f будет указывать на стандартный выходной файл.
После обращения к append файл f становится доступным только на запись, и Eof(f) принимает всегда значение True(истина).
Рассмотрите несколько примеров простых программ.
Program TextFile4; Var |
Program TextFile5; Var |
Program TextFile6; Var |
Стандартные текстовые файлы Input и Output. Примеры задач
В Паскале существуют два стандартных текстовых файла: Input и Output. Эти файлы считаются известными в любой Pascal-программе (иными словами, они описаны в стандартном модуле System). Они обозначают (по терминологии MS-DOS), соответственно, стандартный файл ввода и стандартный файл вывода. Обычно эти стандартные файлы связаны с конкретными физическими устройствами компьютера. Так, файловая переменная Input связана с клавиатурой, файловая переменная Output — с экраном дисплея. Эти файлы считаются заранее открытыми, а соответствующие идентификаторы можно использовать в операциях ввода-вывода.
Рассмотрим, например, следующий оператор:
writeln (Output, ‘Результат равен ‘, (X+Y)*2); |
В соответствии с общими правилами, этот оператор выведет значения двух последних операндов в текущую строку заданного файла, а затем произведет переход к следующей строке. В применении к стандартному файлу Output эти действия будут выглядеть как появление в текущей строчке дисплея литеральных изображений указанных значений, после чего курсор будет перемещен в первую позицию следующей строки.
Аналогично, оператор read (Input, X1, X2); будет выполняться таким образом: система перейдет в состояние ожидания ввода с клавиатуры двух значений. Типы вводимых значений должны совпадать с типами переменных Х1 и Х2. Эти значения при вводе должны отделяться друг от друга одним или несколькими пробелами, а ввод должен быть завершен нажатием клавиши Enter. В процессе ввода значений набираемые на клавиатуре символы отображаются на экране. После нажатия Enter введенные значения будут присвоены переменным Х1 и Х2, и выполнение программы будет продолжено.
Для стандартных файлов Input и Output допускается сокращенная форма записи операций ввода-вывода. Так, если в процедурах read и readln первый параметр опущен, то по умолчанию подразумевается файл Input. Аналогично, отсутствие в процедурах write и writeln первого параметра означает вывод в стандартный файл Output. Вывод в стандартный файл Output используется очень часто — всегда, когда необходимо выдать некоторую информацию из программы на экран.
В соответствии с общими правилами MS-DOS стандартные файлы ввода-вывода могут быть «переназначены», то есть, связаны с другими физическими устройствами или дисковыми файлами. Простейшим способом переназначения является использование для этой цели процедуры assign, например,
assign (Output,’MyFile.out’); |
После выполнения такого оператора стандартный файл вывода будет переназначен, то есть файловая переменная Output будет связана с дисковым файлом MyFile.out из текущего каталога. Все операции вывода, явно или неявно работающие с файлом Output, будут выводить информацию в указанный дисковый файл.
Задание. Рассмотрите предложенные программы, наберите их на компьютере, выделите необходимые части алгоритма в подпрограммы, сформулируйте решаемые ими задачи, дополните необходимыми операторами и комментарием.
Program StringCount; Uses Crt; Var i : integer; s : string; f : text; Begin ClrScr; readln(s); assign(f, s); reset(f); i := 0; while not Eof(f) do begin readln(f,s); i:=i+1; end; close(f); writeln(i); readln; End. |
Program Zamen; Uses Crt; Var s : string; f, d : text; Begin ClrScr; readln(s); assign(f, s); readln(s); assign(d, s); reset(f); rewrite(d); while not Eof(f) do begin readln(f, s); while Pos(‘o’, s)>0 do s[Pos(‘o’, s)] := ‘a’; writeln(d, s); end; close(f); close(d); readln; End. |
Program MaxInFile; Uses Crt; Var i, j, r, Code : integer; s : string; f : text; Begin ClrScr; readln(s); assign(f, s); reset(f); while not Eof(f) do begin readln(f, s); j:=0; for i:=1 to Length(s) do begin Val(s[i], r, Code); if r>j then j:=r; end; writeln(j); end; close(f); readln; End. |
Нетипизированные файлы. Их особенности. Процедуры blockread и blockwrite
Нетипизированные файлы — это файлы, поддержка которых осуществляется с максимально возможной скоростью. Введение таких файлов в систему Турбо Паскаль было вызвано стремлением повысить эффективность программ, участвующих в интенсивном обмене с внешними наборами данных.
Нетипизированный файл рассматривается в Паскале как совокупность символов или байтов. Выбор char или byte не играет никакой роли, важен лишь объем занимаемых данных.
Такое представление стирает различия между файлами независимо от типа содержащейся в них информации. На практике это приводит к тому, что любой файл, подготовленный как текстовый или типизированный, можно открыть и начать работу с ним, как с нетипизированным набором данных.
Для определения в программе нетипизированного файла служит зарезервированное слово file:
Var MyFile : file; |
Реализация работы с такими файлами наиболее полно соответствует аппаратной поддержке операций с внешними носителями. За счет этого достигается максимально возможная скорость доступа к наборам данных. Для нетипизированных файлов не нужно терять время на преобразование типов и поиск управляющих последовательностей, достаточно считать содержимое файла в определенную область памяти.
Нетипизированный файл является файлом прямого доступа, что говорит о возможности одновременного использования операций чтения и записи.
Для таких файлов самым важным параметром является длина записи в байтах. Открытие нетипизированного файла с длиной записи в 1 байт можно выполнить следующим образом:
rewrite(MyFile, 1) или reset(MyFile, 1)
Второй параметр, предназначенный только для использования с нетипизированными файлами, задает длину записи файла на сеанс работы.
Особенность аппаратной поддержки заключается в том, что при обращении к внешнему устройству минимально возможным объемом для считывания являются 128 байт. В стремлении добиться наибольшей эффективности файловых операций в Турбо Паскале принято соглашение, по которому длина записи нетипизированного файла по умолчанию составляет 128 байт. Поэтому после открытия файла с помощью вызовов:
rewrite(MyFile) или reset(MyFile)
все процедуры и функции, обслуживающие файлы прямого доступа, работают с записями длиной 128 байт.
Каждый пользователь для своих программ может выбрать наиболее подходящий размер записи. Турбо Паскаль не накладывает каких-либо ограничений на длину записи нетипизированного файла, за исключением требования положительности и ограничения максимальной длины 65535 байтами. При этом следует учитывать два обстоятельства.
Во-первых, для обеспечения максимальной скорости обмена данными следует задавать длину, которая была бы кратна длине физического сектора дискового носителя информации (512 байт).
С другой стороны, нужно помнить, что общий размер файла может не быть кратен выбранному размеру записи (последняя запись может быть неполной). Для того, чтобы гарантированно обеспечить полное чтение всего файла, рекомендуется установить размер записи равным 1.
Более того, фактически пространство на диске выделяется любому файлу порциями — кластерами, которые в зависимости от типа диска могут занимать 2 и более смежных секторов. Как правило, кластер может быть прочитан или записан за один оборот диска, поэтому наивысшую скорость обмена данными можно получить, если указать длину записи, равную длине кластера.
При работе с нетипизированными файлами могут применяться следующие процедуры и функции, применимые к типизированным файлам:
assign (МуFilе, ‘с:\МуDirectory\result.dat’) — процедура связывания логической файловой переменной МуFilе с конкретным физическим файлом на дисковом носителе информации;
closе (МуFilе) — процедура, закрывающая открытый файл;
rewrite (МуFilе) — процедура, создающая новый файл и открывающая его для записи и чтения; при работе с нетипизированными файлами эта процедура имеет дополнительный параметр, который был рассмотрен выше;
reset (МуFilе) — процедура, открывающая существующий файл данных для чтения и записи; при работе с нетипизированными файлами эта процедура имеет дополнительный параметр, который был рассмотрен выше;
eof (МуFilе) — логическая функция, проверяющая, достигнут ли конец файла;
seek (МуFilе, n) — процедура, позволяющая явно изменить значение текущего указателя файла, установив его на элемент с номером n;
filepos (МуFilе) — функция, возвращающая позицию указателя файла; нумерация начинается с нуля;
filesize(МуFilе) — функция, возвращающая количество элементов файла;
rename(МуFilе, FileName) — процедура, позволяющая переименовать существующий файл;
truncate(МуFilе) — процедура, позволяющая удалить часть существующего файла, начиная с текущей позиции и до конца файла;
erase(МуFilе) — процедура, стирающая указанный файл,
Вы должны были заметить, что в списке нет процедур read и write. Для чтения информации из нетипизированного файла и записи информации в него только для данного типа файлов в Турбо Паскаль введены две новые процедуры, поддерживающие операции ввода-вывода с более высокой скоростью.
Процедура BlockRead
blockread(Var F : file; Var Buf; Kol : word; result : word); |
Процедура считывает из файла F определенное число записей в память, начиная с первого байта переменной Buf.
Параметр Buf представляет любую переменную, которая будет участвовать в обмене данными с дисками. Эту переменную нужно описать в программе так, чтобы ее размер не был меньше размера записи, установленного в параметрах rewrite или reset (как правило, для этих целей используется некоторый массив).
Параметр Kol задает число считываемых записей.
Параметр result является необязательным и содержит после вызова процедуры число действительно считанных записей.
Использование параметра result подсказывает, что число считанных блоков может быть меньше, чем задано параметром Kol. Если result указан при вызове, то ошибки ввода-вывода в такой ситуации не произойдет. Для отслеживания этой и других ошибок чтения можно использовать опции , и функцию IOresult.
Кроме того, что переменная F должна быть описана как нетипизированный файл, она должна быть связана с конкретным физическим диском процедурой assign, и файл должен быть открыт.
Процедура BlockWrite
blockwrite(Var F : file; Var Buf; Kol : word; result : word); |
Процедура предназначена для быстрой передачи в файл F определенного числа записей из переменной Buf. Все параметры процедуры BlockWrite аналогичны параметрам процедуры BlockRead. Содержимое переменной Buf в количестве Kol записей помещается в файл, начиная с текущего положения указателя файла.
Обе процедуры выполняют операции ввода-вывода блоками. Объем блока в байтах определяется по формуле:
Объем = Kol * recSize,
где recSize — размер записи файла, заданный при его открытии. Суммарный объем разового обмена не должен превышать 64 Кбайт.
Помимо скорости передачи данных преимущество этих процедур заключается в возможности пользователя самостоятельно определять размер буфера для файловых операций. Эта возможность играет значительную роль в тех задачах, где необходимо жесткое планирование ресурсов. Программист должен позаботиться о том, чтобы длина внутреннего представления переменной Buf была достаточной для размещения всех байт при чтении информации с диска. Дело в том, что чтение информации из файла в буфер, равно как и запись из буфера в файл, производится без типового контроля. Поэтому несоблюдение указанного условия может привести к порче соседних с буфером данных или к помещению в файл посторонней информации.
Возможна ситуация, когда при чтении в файле содержится менее Kol записей или в процессе записи на диске не окажется нужного свободного пространства. В этом случае, если параметр result в процедуре BlockRead (BlockWrite) не был задан, то возникнет ошибка ввода-вывода; в противном случае ошибка не будет зафиксирована, а после выполнения процедуры значение параметра result не совпадет со значением параметра Kol и будет равно количеству фактически прочитанных (записанных) записей. Последнее обстоятельство можно проверить, сравнив два указанных значения.
После завершения процедуры указатель смещается на result записей.
Рассмотрите примеры простых задач.
Задача 1. Составить программу, которая создает нетипизированный файл из 100 чисел и выводит на экран k-ый элемент.
Program Netipiz1; Uses Crt; Type FileType = file; Var f : FileType; P, k : byte; Begin ClrScr; assign(F, ‘MyFile’); rewrite(F,1); Randomize; for k := 1 to 100 do begin P := Random(100); blockwrite(F, P, 1); end; close(F); reset(F,1); for k := 1 to 100 do begin blockread(F, P, 1); write(p,’ ‘); end; write(‘Введите номер нужного элемента ‘); readln(k); Seek(F, k-1); blockread(F, P, 1); writeln(k,’-ий элемент файла равен ‘, P); close(F); End. |
Задача 2. Составить программу, которая создает копию элементов нетипизированного файла f и помещает в файл g.
Program Netipiz2; Uses Crt; Var f, g : file; s : char; Stroka1, Stroka2 : string; Begin ClrScr; write(‘Введите имя исходного файла: ‘); readln(Stroka1); assign(f, Stroka1); rewrite(f, 1); writeln(‘Введите содержимое файла ‘); readln(s); while s <> #13 do begin blockwrite(f, s, 1); readln(s); end; close(f); reset(f, 1); write(‘Введите имя конечного файла: ‘); read(Stroka2); assign(g, Stroka2); rewrite(g, 1); while not Eof(f) do begin blockread(f, s, 1); blockwrite(g, s, 1); end; close(f); close(g); reset(g, 1); writeln(‘Содержимое конечного файла:’); while not Eof(g) do begin blockread(g, s, 1); write(s); end; close(g); readln; End. |
Задача 3. Составить программу, которая создает массив целых чисел и записывает его в нетипизированный файл, а также вычисляет среднее арифметическое элементов файла.
Program Netipiz3; Uses Crt; Var f : file; i, k, s : integer; Mas : Array [1..10] of byte; Begin ClrScr; Randomize; for i := 1 to 10 do begin Mas[i] := Random(10); write(Mas[i]:3); end; assign(f, ‘file.dat’); rewrite(f, 1); blockwrite(f, Mas, 10); close(f); reset(f,1); S:=0; i:=0; while not Eof(f) do begin blockread(f, k, 1); s:= s+k; Inc(i); end; close(f); writeln; write(s/i:5:2); readln; End. |
Задание. Наберите приведенные выше тексты программ, убедитесь в их работоспособности.
Использование текстовых файлов в качестве нетипизированных
Задача. Прочитать текстовый файл и заменить находящиеся там символы новыми, отличающимися своими кодами от исходных на определенную величину, изменяющуюся от символа к символу (шифрование методом простой одноалфавитной подстановки). Поместить зашифрованный текст в новый файл, разместив в нем предварительно число перекодированных символов и таблицу смещений кодов.
Program Kodirovka; Const NofCod = 20; Var FirstFile : text; SecondFile : file; FirstName, SecondName : string; IOres : byte; NofSymb : LongInt; Codes : Array[1..NofCod] of byte; Buffer : Array [1..NofCod] of char; i : word; symbol : char; Procedure WriteAndControl (Var Buf; Amount : word); repeat write(‘Имя исходного файла: ‘); IOres := IOresult; repeat write(‘Имя результирующего файла: ‘); IOres := IOresult; NofSymb := 0; Randomize; i := 0; if i <> 0 NofSymb := FileSize(SecondFile)-NofCod-4; close(SecondFile); |
В этой программе в результирующий файл окончательно будут записаны: общее количество перекодированных символов, таблица смещений кодов символов и перекодированные символы. Выходной файл используется как нетиризированный с размером записи в 1 байт.
Дополнительные процедуры и функции для работы с файлами
Рассмотрим три процедуры из модуля System.
Изменение имени файла производится процедурой
rename(МуFilе, FileName); |
первый аргумент которой — переменная файлового типа, а второй аргумент — строкового типа — новое имя файла, которое может быть сокращенным или полным (с указанием пути). Действие этой процедуры эквивалентно действию аналогичной процедуры DOS.
Уничтожение части файла от текущего положения указателя до конца файла производится процедурой
truncate(МуFilе); |
Процедура применима к любым типам файлов, кроме текстовых; файл должен быт предварительно открыт.
Уничтожение всего файла производится процедурой
erase(МуFilе); |
действие которой эквивалентно удалению файла в операционной системе DOS. Процедура неприменима к открытым файлам.
Рассмотрим некоторые процедуры работы с файлами, входящие в модуль Dos. Напомним, что для его подключения требуется указать
Ряд свойств файла, хранящегося на диске, кодируются так называемыми атрибутами. Атрибуты файла записываются не в сам файл, а в информационный раздел каталога, в котором хранится файл. Для хранения атрибутов отводится один байт, единица в определенном бите которого означает наличие свойства, а нуль — отсутствие. Соответствие битов и свойств показывает схема, приведенная на рисунке.
0 — Только чтение ReadOnly=1,
1 — Скрытый файл Hidden=2,
2 — Системный файл SysFile=4,
3 — Метка тома VolumeID=8,
4 — Подкаталог Directory=16,
5 — Архивный файл Archive=32,
Произвольный файл AnyFile=63.
Каждому атрибуту соответствует определенная константа, равная 2 k , где k — номер бита. Эти константы описаны в модуле Dos, их значения и имена приведены на схеме. В целом байт атрибутов образуется как сумма соответствующих ему констант. Установка атрибута «только чтение» приводит к невозможности изменения содержимого файла или его удаления.
Скрытые файлы игнорируются некоторыми командами операционной системы, в частности, они не показываются по команде Dir. Системные файлы — файлы операционной системы Dos. Атрибут «Архивный» означает, что для этого файла не была создана резервная копия командой BackUp.
Большинство файлов имеют этот атрибут. Определить атрибуты файла можно с помощью процедуры
GetFAttr(MyFile, Attr); |
которая возвращает переменную Attr типа word, содержащую код атрибутов файла.
Например, проверить свойство «только для чтения» можно следующим образом:
GetFAttr(MyFile, Attr); if Odd(Attr) then write (‘Только для чтения’) else write(‘Не только для чтения’); |
Установка требуемых атрибутов файла производится процедурой
setFAttr (MyFile, Attr); |
Процедуры для поиска на диске требуемых файлов используют специальный тип записи SearchRec, определенный в модуле Dos. Запись
Туре SearchRec= record Fill : аrrау [1..21] оf bytе; Attr : bytе; Time : longint; Size : longint; Name : string[12] end; |
Первое поле записи — массив Fill — используется операционной системой и не должно изменяться в пользовательских программах. Содержание поля Attr — атрибуты файла, рассмотренные выше. Поле Time содержит дату и время записи файла в упакованном виде, для распаковки служит процедура UnpackTime. Size — размер файла в байтах. Name — имя файла, включая разделительную точку и расширение.
FindFirst (SearchPath, Аttr, SearchResult); |
ищет в каталоге первый файл, удовлетворяющий заданной спецификации. Параметры SearchPath и Аttr содержат исходные данные для поиска. Возвращаемый результат поиска — SearchResult — запись типа SearchRec. SearchPath — строка, содержащая полное имя файла, в том числе каталог, в котором необходимо искать файл, и имя файла. Имя файла (но не путь) может содержать символы звездочки и вопросительного знака, которые, соответственно, заменяют любую последовательность символов или один произвольный символ.
Если путь не приводится, поиск идет в рабочем каталоге. Следовательно, SearchPath = ‘*.dat’ указывает на все файлы с расширением «dat» в текущем каталоге.
Процедура FindNext(SearchResult) употребляется только после процедуры FindFirst и продолжает последовательно поиск файлов с определенным процедурой FindFirst шаблоном.
Функция FSearch(SearchString, DirList) ищет файл, заданный строкой SearchString, в заданном списке каталогов DirList. Список каталогов записывается так же, как в команде DOS Path, то есть различные каталоги разделены точкой с запятой. Результат этой функции — полное имя файла, если он найден по указанным путям.
Функция FExpand(FileName), получив имя файла FileName, расширяет его до полного имени, используя для этого имя текущего каталога. Если в качестве FileName задано имя с полным путем, функция не изменяет его. Если задано только имя файла, то дописывается текущий каталог. Если запись FileName начинается с символа «обратный слэш», то берется текущий диск и к нему дописывается имя FileName. Если запись FileName начинается с символов «..», то берется часть имени текущего каталога на уровень выше.
Процедура FSplit(WholeFileName, Dir, Name, Ext), получив в качестве аргумента полное имя файла WholeFileName, разделяет его на три составные части и возвращает переменные параметры Dir — каталог, Name — имя файла, Ext — расширение. Для каталога, имени файла и расширения в модуле DOS предусмотрены специальные типы — строки ограниченной длины: PathStr, NameStr, ExtStr.
Многие подпрограммы модуля Dos используют переменную DosError для указания на результат выполнения операции. Нулевое значение переменной указывает на отсутствие ошибок, ряд других возможных значений DosError приведен в таблице:
Код 2 3 5 8 18 | Значение Файл не найден Путь не найден Нет доступа Недостаточно памяти Больше нет файлов (при поиске) |
Обратим внимание, что типизированные переменные пишутся в файл в том виде, в каком они используются в памяти ЭВМ. Если мы пытаемся прочитать содержимое такого файла обычными средствами DOS, например, нажав F3 в Norton Commander, или непосредственно в среде Паскаль, то каждый байт этих записей воспроизведется как соответствующий символ кодовой таблицы ASCII. Например, если файл имеет байтовый тип, и в него пишутся числа 65, 66, 67, то при его чтении мы увидим АВС. Такая запись данных компактна и удобна, если создаваемые файлы читаются другими программами, для которых эта кодировка естественна. В тех случаях, когда файлы предназначены для просмотра человеком, требуется перевод данных в текстовую форму.
Внешние устройства в качестве файлов
Связь с внешними устройствами в языке Паскаль осуществляется также через файловые переменные.
В Турбо Паскале существует два типа внешних устройств: устройства операционной системы и текстовые устройства.
Устройства операционной системы, с которыми осуществляется обмен информацией, могут быть описаны как файлы со стандартными именами. Эти имена следующие:
CON — консоль (клавиатура, дисплей). С этим устройством стандартно связаны файловые переменные Input и Output.
LPT1, LPT2, LPT3 — печатающие устройства. Если в системе один принтер, то он будет иметь имя LPT1. Если в программе используется стандартный модуль Printer (указан в разделе Uses), можно использовать для вывода на принтер стандартную файловую переменную Lst.
PRN — синоним LPT1.
COM1, COM2 — имена двух последовательных портов.
AUX — синоним COM1.
NUL — фиктивное внешнее устройство.
К текстовым устройствам относятся устройства, не поддерживаемые операционной системой или имеющие другие способы обращения. Например, устройство CRT, поддерживаемое стандартным модулем Сrt. Оно эквивалентно CON в операционной системе, но более быстродействующее и позволяет использовать разные цвета и окна.
С текстовым устройством нельзя связаться процедурой assign. Для связи с ним служит специальная модификация этой процедуры, например, для связи с устройством CRT следует использовать процедуру AssignCrt в модуле Crt.