Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Книга Фортран Павловец 2008

.pdf
Скачиваний:
127
Добавлен:
31.05.2015
Размер:
1.55 Mб
Скачать

В результате получим линию из 32 символов « = », ниже 4 строки по 3 числа с элементами массива С, затем полученная таблица подчеркнута линией символов « = ».

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

Файлы разделяют на:

файлы последовательного доступа

файлы прямого доступа.

Все они состоят из записей (запись – строка информации, которая может содержать текст или числовые данные).

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

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

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

-форматно;

-бесформатно;

-в двоичных кодах.

Примечание:

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

Двоичная форма записи предпочтительна в тех случаях, когда информация будет использоваться в других языках программирования (например: Паскаль или С).

Каждый файл имеет следующую структуру:

имя файла

запись

запись

конец файла

33. Открытие файлов

Открытие файлов осуществляется или явно с помощью оператора OPEN или неявно с помощью операторов READ или WRITE.

Пример:

OPEN( UNIT=3, FILE=’WHOD.DAT’, STATUS=’OLD’, ACCESS=’SEQUENTIAL’)

номер канала

имя файла

тип файла

способ доступа

81

UNIT=3 – означает открыть файл по каналу номер 3. Слово UNIT= можно опустить. FILE – имя файла, который открывается. Если файл открывается в другом каталоге, то

указывается полный путь к нему из корневого каталога. Если файл в текущем каталоге, то путь файла не указывается.

Имя файла может быть задано текстовой константой, заключенной в апострофы, или текстовой переменной (см. раздел «Работа с текстом»), текстовым массивом.

STATUS – тип файла (встречается редакция транслятора, где используется слово TYPE):

1)OLD – старый. Он заранее должен был быть записан на диск. Этот файл мог быть создан текстовым редактором или в результате выполнения другой программы. Если указано ключевое слово OLD, а такой файл на диске не найден, то выдастся сообщение:

File not found (файл не найден).

Вместо запланированного имени файла WHOD.DAT можно указать имя другого файла или указать устройство "консоль" CON (дисплей). При вводе ввести данные можно с клавиатуры, а при выводе вывести информацию на экран..

2)NEW – новый. При этом на диске создаётся новый файл с указанным именем WHOD.DAT. Этот файл открывается и в него будут записываться результаты вычислений. Если указано ключевое слово NEW, а на диске уже существует файл WHOD.DAT, то этот старый файл уничтожается, а на его месте открывается новый;

3)UNKNOWN – неопознанный. При UNKNOWN осуществляется поиск файла с указанным именем как старого файла (OLD) и этот файл открывается для обработки. Если файла с указанным именем не обнаружено, то создаётся новый файл с таким же именем.

Если параметр STATUS не указан, то по умолчанию файл принимается типа

UNKNOWN.

ACCESS – способ доступа к файлу. SEQUENTIAL – последовательный. DIRECT – прямой.

Если параметр ACCESS не указан, то по умолчанию принимается файл последовательного доступа SEQUENTIAL.

Работа оператора OPEN с файлами предусмотрена внутри своего каталога. Для того чтобы обратиться к файлу, находящемуся в другом каталоге, необходимо указать полный путь к этому файлу, начиная от корневого каталога.

Номера каналов могут быть любые: от 1 до 77 в восьмеричной системе исчисления (исключая цифры 8,9). Необходимо помнить, что каналы номер 5 и 6 зафиксированы для ввода (с клавиатуры) и вывода информации (на дисплей). Но, если открыть файл по каналу 5, то произойдет переназначение канала номер 5 и весь ввод информации по каналу 5 будет осуществляться из файла, а не с клавиатуры.

Одновременно может быть открыто до 20 файлов (количество открытых файлов зависит от настройки конкретной версии операционной системы). По одному каналу (например, номер 3) может быть открыт только один файл. Чтобы по этому каналу открыть другой файл, необходимо предыдущий файл закрыть, а нужный открыть.

Неявное открытие файла может осуществляться без оператора OPEN, если мы в операторе READ или WRITE укажем номер канала, который раньше в этой программе не открывался или уже был закрыт.

Пример:

READ (4,7) A,B

В этом случае компьютер выведет запрос:

File name missing or blank. Please, enter the file name. UNIT4? ____

82

После запроса мы должны задать или имя файла, из которого будет читаться информация или обозначить устройство, с которого будет считываться информация. Можно ввести, например, имя файла DANU.DAT – имя файла данных; или CON – устройство консоль (ввести данные с клавиатуры дисплея). Если при выводе WRITE(4,7)A,B файл по каналу 4 не открыт и компьютер выдает аналогичный запрос, то можно указать устройство PRN – принтер (тогда вся информация, которая будет выводится по каналу 4, будет выводится на принтер).

Закрытие файла осуществляется при помощи оператора CLOSE.

CLOSE (UNIT=3), или CLOSE(3).

Затем по этому каналу можно открыть другой файл:

OPEN(3, FILE=’WYHOD.REZ’)

Самый простой способ открытия файла:

OPEN(4, FILE='_') – открыть по 4 каналу временный файл (вместо имени – пробел), этот файл при завершении программы удаляется автоматически.

Правило:

Одновременно не может быть открыто количество файлов больше заданного в операционной системе (обычно 20). Все открытые файлы должны быть закрыты оператором CLOSE или они автоматически закрываются при завершении работы программы.

Деловой совет:

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

34. Непосредственная работа с файлом

При выполнении оператора OPEN открывается файл по указанному каналу и указатель считывания записи устанавливается на первую запись.

Указатель считывания записи – аппаратная величина, которую мы наблюдать не можем. Указатель считывания записи перемещается от одной записи к другой при выполнении READ или WRITE, а при форматной обработке информации при выполнении символа слэш « / » оператора FORMAT.

Пример:

READ(5,7)

7 FORMAT(///) – пропустить 3 записи и начать обработку информации с 4-й строки.

Бесформатный вывод информации достаточно прост. Пример работы с файлом:

OPEN(2, FILE=’WYHOD.REZ’, STATUS=’NEW’) WRITE (2,*)’ A=’,A,’ B=’,B

WRITE (2,*)

83

WRITE (2,*) ’Результат расчёта’

WRITE (2,*) ’сумма =’,S

Эта информация появится в файле так же, если бы она выводилась на экран дисплея. WRITE(2,*) без списка вывода выведет в файле пустую строку.

А вот при бесформатном чтении информации из файла необходимо учитывать некоторые особенности.

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

-1.5,2.7 3.8,6.5,1.7 8.9,-1.65,8.3 2.1,3.8,0. 6.3,4.5 -15.75,-6.9 3.8,-2.5

Файл записан на жесткий диск. Попробуем читать содержимое файла и отметим особенности выполнения операций

OPEN(3, FILE =’DAN1.DAT’, STATUS=’OLD’)

READ(3,*)A1,B1 При чтении файла переменным будут присваиваться значения A1=- 1.5, B1=2.7

READ(3,*)A2,B2 Переменным будут присвоены значение A2 =3.8, B2=6.5. Число 1.7 из второй записи не прочтется, так как закончился список ввода.

READ(3,*) По этому оператору третья запись будет пропущена без чтения, так как в операторе отсутствует список ввода.

READ(3,*)A4,B4,C4,D4 Здесь список ввода больше, чем количество данных в следующей записи. Поэтому при бесформатном вводе получим A4=2.1, B4=3.8, C4=0., а значение D4 прочтется автоматически из следующей, пятой по счету записи D4=6.3 . Число 4.5 из пятой записи останется непрочитанным.

READ(3,*)F Прочтется число -15.75

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

WRITE(3,*)’Результаты расчета S= ’, S,

то в файл выведется информация из оператора WRITE. Но при этом вся информация от места вывода до конца файла 3.8,-2.5 будет уничтожена. Предыдущая информация останется.

Внимание! Если мы прочитали файл последовательного доступа не до конца и в каком-либо месте сделали вывод в этот файл, то вся информация от этого места до конца файла будет уничтожена.

Но вывод информации в этот файл можно продолжать.

84

35. Форматный вывод информации

Форматный вывод информации рассмотрим на примере (аналогичен простому форматному выводу на экран):

Пример:

OPEN(3, FILE=’WYHOD.REZ’, STATUS=’NEW’)

WRITE (3,7) A,B,C, (I,D(I),I=1,N)

7FORMAT(//1X,’A=’,F6.2,T12,'B=',F4.1,5X, 'C=',F5.2/1Х,'Массив D'/

*(1X,I2, 2X,E10.3/))

Обратите внимание на вывод массива D. После символа / в операторе FORMAT перед скобками, определяющими группу спецификаций (1X,I2,2X,E10.3/), не стоит количество повторений. Это обозначает, что указанная группа будет повторяться бесконечное количество раз до тех пор, пока не будет исчерпан список вывода. В каждой новой строке будет выводиться номер элемента массива D и его значение в форме числа с плавающей запятой с тремя значащими цифрами.

36. Форматное чтение информации из файла

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

Текстовым редактором создаётся файл исходных данных (например, ISH.DAN). Предположим, что он будет иметь следующее содержание:

 

Программа расчёта магнитного поля

 

Автор Иванов И. И.

 

3 строки

позиции:

|12-я

|28-я

 

Радиус обмотки внутренний

_0.260

 

 

Радиус обмотки внешний

_0.527

 

 

Высота обмотки Н

_0.400

 

 

Значение тока

_ _6

 

 

 

 

 

 

Расчёт магнитного поля на оси

 

 

 

по высоте от

_0.0

 

 

до

_1.2

 

 

 

 

 

Задача:

1)Прочитать информацию из файла.

2)Произвести вычисление по заданию.

3)Результаты расчёта поместить в этот же файл.

85

СПрограмма №28 DIMENSION B(100)

OPEN(UNIT=3, FILE=’ISH.DAN’, STATUS=’OLD’) READ (3,8) RB,RBN,H,I,HN,HK

8FORMAT(///3(28X,F6.3/)28X,I3//28X,F4.1/28X,F4.1/)

Пропускаем 3 строки. Затем с четвертой строки три раза идет чтение: пропускаем 28 символов и читаем число RB по формату F6.3; переходим на пятую строку, пропускаем 28 позиций и читаем число RBN; переходим на шестую строку, пропускаем 28 позиций и читаем число H, переходим на новую строку. Пропускаем 28 позиций и читаем значение тока I по формату I3. Пропускаем две строки, затем 28Х и читаем HN,

переходим на новую строку, 28Х и читаем HK. Пропускаем еще одну строку с чертой. Когда оператор FORMAT завершает свою работу, указатель считывания записи перемещается на 1 строку вниз.

CДопустим, количество точек

N=50

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

CALL INDUK(RB,RBN,H,I,HN,HK,B,N)

CВывод информации

WRITE (3,10) (J,B(J),J=1,N)

10FORMAT(/1X, ’Результаты расчета’/(1X,'B(',I3,')=',G10.4/))

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

уничтожена. Весь массив будет выведен в один столбец в виде В(1)=_.1234Е+12.

После второго символа « / » перед группой спецификаций, заключенной в скобки, не стоит количество повторений. Это значит, что данная группа спецификаций будет повторяться бесконечное количество раз до тех пор, пока не будет исчерпан список вывода оператора WRITE.

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

1)создать массив значений аргумента;

2)вычислять текущее значение высоты Н в процессе вывода информации и выводить это значение:

HT=HN+(J–1)*(HK–HN)/(N–1)

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

86

WRITE (3,10) (HN+(J–1)*(HK–HN)/(N–1), B(J),J=1,N)

10FORMAT(/1X,’Результат расчёта’/(1X,’При H=’,F4.2, *’B=’,G11.4/))

WRITE (3,11)

11FORMAT (1X,70(’=’)) CLOSE(3)

PAUSE STOP END

Однако желательно избегать сложных арифметических выражений в операторе вывода

WRITE.

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

$INCLUDE.

Она записывается в том месте текста головной программы, куда нужно вставить текст подпрограммы. Записываем в программе с первой позиции строки метакоманду:

$INCLUDE: ’INDUK.FOR’

Если этот файл находится в другом месте, то необходимо указать полный путь к нему $INCLUDE: ’D:\Fortran\MyProg\INDUK.FOR’

Метакоманда начинается символом « $ » с первой позиции, а в данном случае INCLUDE включает в текст программы имя файла, который указан в текстовой строке.

37. Обработка сбойных ситуаций и ситуаций «конец файла» при вводе-выводе информации

Оператор ввода в полном виде имеет следующую структуру:

READ (n, m1, ERR=m2, END=m3) список, где n – номер канала ввода;

m1 – метка оператора FORMAT или «*» ;

m2 – метка оператора, по которому передаётся управление, если при вводе информации произошёл сбой по чтению.

Сбойная ситуации наступает в том случае, когда вводимая информация не соответствует описанию полей оператора FORMAT. Например: целое число вводится с десятичной точкой; вещественное число вводится с двумя минусами; число не соответствует формату; вместо числовой информации вводится текстовая информация (распространённая ошибка); при форматном вводе ставится запятая, которая является ошибкой при отделении одного числа от другого.

m3 – метка, на которую передаётся управление, если при попытке чтения очередной записи обнаружен конец файла.

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

87

Обработка сбойной ситуации

Пример обработки сбойных ситуаций при вводе исходных данных с экрана дисплея:

OPEN (4,FILE=’REZ.DAT’) Самый простой способ открытия файла со статусом UNKNOWN

7WRITE (6,*) ’Введите A,I,B’

READ (5,8,ERR=11) A, I, B При сбойной ситуации во время чтения информации управление будет передано на метку 11

8FORMAT (F6.2,I4,E9.3)

WRITE (4,12) A,I,B Прочитанные исходные данные выводятся в файл результатов REZ.DAT

12 FORMAT(2X,’Исходные данные’/4X,’A=’,F7.2,’ I=’,I4,’ B=’,G12.4)

Формат вывода данных может отличаться от формата ввода.

GOTO 13

11 WRITE (6,*) ’При вводе ИД произошёл сбой. Введите ИД заново по

*формату F6.2, I4, E9.3’ GO TO 7

13D=A+B

Если при вводе информации в данной программе произошла ошибка, то управление передаётся на метку 11. По этой метке мы выдаём текстовое сообщение об ошибке и подсказку, как эту ошибку исправить. После этого повторяем ввод исходных данных.

Обработка ситуации «конец файла»

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

OPEN (4,FILE=’DAN.DAT’)

7READ (4,8,END=14) A,I,B Читаем три числа по формату с меткой 8. Если вместо чисел будет обнаружен конец файла, то управление будет передано на метку 14

8FORMAT (F6.2,I4,E9.3)

WRITE (6,12) A,I,B

12FORMAT (2X,’Прочитали’,4X,’A=’,F7.2,’ I=’,I4,’ B=’,G11.4) WRITE (6,*)’Вычисляем’

GO TO 7 Переходим к чтению

14 WRITE (6,*)’При чтении ИД обнаружен конец файла.’

STOP

END

88

Задача:

Система передачи данных записывала в файл информацию U, I, cosφ, t о нагрузке, потребляемой предприятием. При каждом скачкообразном изменении нагрузки записывается новая запись (количество записей неизвестно). Подсчитать количество записанных записей, а так же количество электроэнергии, потреблённой нагрузкой за истекший период.

Q = P t

n1

Q = Pi (ti+1 ti )

1

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

СПрограмма №29 DIMENSION P(1000),T(1000)

OPEN (4,FILE=’NAGR.DAT’,STATUS=’OLD’) I=1

KZ=0 Задаем переменную КZ – счетчик количества прочитанных записей

11 READ (4,*,END=8) U,TOK,CF,T(I) При достижении конца файла управление будет передано на метку 8

P(I)=U*TOK*CF Формируем массив со значениями потребляемой мощности

KZ=KZ+1

К счетчику количества прочитанных записей

прибавляем единицу

 

I=I+1 GOTO 11

8 WRITE (6,*)’Количество записей=’,KZ SQ=0.

DO 12 J=1,KZ–1

12SQ=SQ+P(J)*(T(J+1)–T(J))

WRITE (6,*)’Количество электроэнергии =’,SQ CLOSE(4)

PAUSE STOP

END

Следует отметить, что переменную I можно было бы и не вводить, а для заполнения массива использовать переменную KZ.

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

38. Операторы для работы с записями в файле

Коператорам для работы с записями в файле относят:

1)BACKSPACE n – позволяет вернуться на одну запись назад в файле, открытому по каналу номер n.

Пример:

BACKSPACE 3 или BACKSPACE (UNIT=3)

89

Оператор BACKSPACE может повторяться несколько раз или находиться внутри цикла

DO.

DO 2 I=1,4

2 BACKSPACE 3

Если при многократном повторном выполнении BACKAPACE 3 метка считывания записи переместится в самое начало файла, то операция остановится. Указатель считывания записи будет установлен на первую запись.

2)

REWIND n – устанавливает указатель считывания записи в самое начало файла на

первую запись. Файл открыт по каналу номер n;

3)

ENDFILE n – записывает физический признак конца файла на том месте, где

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

39. Дополнение файла информацией

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

Задача:

Вфайле NAGR.DAT хранятся записи, содержащие значения U, I, cosφ, t. Нужно:

1)открыть файл, читать его до конца, затем дополнить его аналогичной информацией. Закончить дополнение файла по сбойной ситуации;

2)подсчитать и выдать количество записей в старом файле и в изменённом.

Первый способ дополнения файла информацией:

СПрограмма №30

OPEN (3,FILE=’NAGR.DAT’,STATUS=’OLD’)

В файле неизвестное количество записей. Неизвестно: форматная запись или нет.

KZAP=0

7READ (3,*, END=8) U,TOK,CF,T KZAP=KZAP+1

GOTO 7

8WRITE (6,*)’В файле было ’,KZAP,’ записей’

Считываем первую запись и счётчик зафиксирует эту запись (KZAP=KZAP+1). По GO TO 7 повторяется чтение новой записи. Когда чтение дойдёт до конца файла, управление передаётся на метку 8. НО ФАЙЛ НЕ ЗАКРЫВАЕТСЯ. Сейчас нам необходимо дополнить файл: в цикле вводить информацию: U, I … с клавиатуры дисплея и записывать эту информацию в файл. Процесс ввода и записи можно повторять бесконечное число раз до возникновения сбойной ситуации.

BACKSPACE 3

WRITE (3,*) U,TOK,CF,T

С помощью последних 2-х строк происходит возвращение назад на одну запись в файле и восстановление последней записи. Без перезаписи

90