- •Операции над внешними файлами
- •Оператор Read
- •Оператор Write
- •Оператор Close
- •Файлы последовательного доступа Форматные файлы
- •Неформатные файлы
- •Файлы прямого доступа
- •Добавление записи в файл прямого доступа.
- •Удаление записи из файла прямого доступа
- •Создание информационно-справочной системы
- •Выбор метода доступа в файле и типа записи
Файлы последовательного доступа Форматные файлы
Форматные файлы последовательного доступа называют еще текстовыми файлами. Текстовый файл содержит символьное представление данных всех типов. При работе с текстовыми файлами используется форматный или управляемый списком ввод/вывод. Записи текстового файла могут иметь разную длину. Одним оператором ввода может быть прочитано произвольное количество записей текстового файла. Текстовый файл может быть создан и просмотрен в любом редакторе, поддерживающим кодировку.
Пример
Создать форматный текстовый файл из 10 целых случайных чисел в диапазоне от -50 до 50 и для контроля вывести его содержимое на экран.
Для создания файла и чтения записанных данных напишем процедуры. Вообще-то для создания файла вручную и просмотра последовательного форматного файла не нужна программа.
program main
implicit none
integer, parameter:: n=10, num=1
character(80) s
print *, 'bb. imj file' ! ввели имя файла
read *, s
! открываем последовательный форматный файл
open(num, file=s, err=10, status='new')
! вызываем процедуру генерации сл.чисел и записи их в файл
call rnd_number (n, num)
rewind(num) !переходим на начало файла
call read_number(num) !выводим содержимое файла на экран
close(num)
stop
!oбработка ошибок
10 print *, 'oшибка записи' !переход в случае ошибки
end program
! Процедура заполнения текстового файла случайными числами
subroutine rnd_number (n,num)
implicit none
integer, intent(in)::n,num
integer i, x
real rnd
call random_seed() !установка стартовой затравки
do i=1, n
call random_number ( rnd )
x=rnd*100 - 50
write (num, *, err=200) x
enddo
return ! возврат в главную программу
!обработка ошибок
200 print *, 'ошибка записи'
end subroutine
subroutine read_number(num)
implicit none
integer,intent(in)::num
integer x
print*, 'Файл случайных чисел'
do while (.not. eof (num))
read(num, *) x !считывание очередного числа из файла
print '(I4, 1x \ )' , x ! вывод на экран
enddo
end subroutine
Пример.
В текстовом форматном файле ( isx.txt ) хранятся вещественные числа. Определить среднее арифметическое и количество чисел больших среднего арифметического, результат записать в другой текстовый файл (res.txt).
В блокноте или в редакторе CVF создадим файл вещественных чисел. Создадим проект и сохраним в нем этот файл. Используем, ранее написанную процедуру control, проверяющую существование файла. Имена входного и выходного файлов введем с клавиатуры.
program main
implicit none
real sr
integer k
character(80) namein,nameout
print *, 'bb imj isx file'
read*, namein
print *, 'bb imj res file'
read*, nameout
call control (namein)
call avg (sr ,k, namein)
call write_file(sr, k, nameout)
end program
subroutine control(s) !проверка наличия файла
implicit none
character(*), intent(in)::s
logical f
inquire(file=s, exist=f)
if (f)then
print*, ‘файл существует'
else
stop ' сначала создайте файл'
!конец работы, если нет файла
endif
end subroutine control
subroutine avg (sr, k, name)
implicit none
character(*),intent(in)::name
real, intent(out):: sr
integer, intent(out)::k
real x, s
integer n
open(2, file=name)
n=0
s=0
do while (.not. eof (2))
read(2,*)x
n=n+1
s=s+x
enddo
sr=s/n
k=0
rewind(2)
do while (.not. eof(2))
read(2,*) x
if(x > sr) k=k+1
enddo
close(2)
end subroutine
subroutine write_file(sr, k, name)
integer, intent(in)::k
real,intent(in)::sr
character,intent(in)::name
open(3, file=name)
write(3, '(5x, A, i3, 2x, A, F4.2)') 'kol=', k, ‘sr=’, sr
close(3)
end subroutine
Пример
Отредактировать исходный файл удалением из него положительных значений.
Program main
Program main
Implicit None
integer x
open(10, file='isxx.txt')
open(20) !, file='wsp.txt', status='scratch')
do while (.not. eof (10))
read(10,* )x
if(x < 0) write (20,*)x
enddo
rewind(10)
rewind(20)
do while (.not. eof (20))
read(20,*) x
write(10,*) x
enddo
close(10)
close(20)
end
Пример
Отредактировать заданный текстовый форматный файл, заменив все максимумы на 999. Количество замен записать в конец файла.
program main
implicit none
integer max, res, max_el, work
character(80) namein, nameout
print *, 'bb imj isx file'
read*, namein
call control_1 (namein)
max= max_el (namein)
res=work (namein, max)
call write_file ( namein, res)
end program
subroutine control_1(s) !проверка наличия файла
implicit none
character(*), intent(in)::s
logical f
inquire(file=s, exist=f)
if (f)then
print*, ‘файл существует’
else
stop 'создайте файл’
endif
end subroutine control_1
! нахождение максимума в файле
integer function max_el name)
implicit none
character(*), intent(in):: name
integer max, x
open(2, file=name)
read(2, *) ,x
max= x
do while (.not. eof (2))
read(2,*)x
if (x>max) max=x
enddo
close(2)
max_el = max
end function max_el
!замена максимумов и нахождение количества замен
Integer function work (name, max)
implicit none
character(*), intent(in):: name
integer, intent(in):: max
integer k, x
! замена максимумов
open (2, file = name)
open (3, file= 'wrm.txt', status='scratch')
k=0
do while (.not. eof (2))
read(2,*) x
if (x == max) then
x=999
k=k+1
endif
write(3,*) x
enddo
! нахождение количества замен
rewind(2)
rewind(3)
do while (.not. eof (3))
read(3,*) x
write(2,*) x
enddo
close(2)
close(3)
work=k
end function work
! дозапись в текстовый файл
subroutine write_file (name, k)
integer, intent(in)::k
character(*), intent(in)::name
open(10, file=name, access='append')
write(10, *) k
close(10)
end subroutine
2-ой вариант программы
( с subroutine work (name, max))
program main
implicit none
integer max, res, max_el, work
character(80) namein, nameout
print *, 'bb imj isx file'
read*, namein
max= max_el (namein)
call work (namein, max)
end program
integer function max_el (name)
implicit none
character(*), intent(in):: name
integer max, x
open(2, file=name)
read(2, *) ,x
max= x
do while (.not. eof (2))
read(2,*)x
if (x>max) max=x
enddo
close(2)
max_el = max
end function max_el
subroutine work (name, max)
implicit none
character(*), intent(in):: name
integer, intent(in):: max
integer k, x
open (2, file = name)
open (3, file= 'wrm.txt', status='scratch')
k=0
do while (.not. eof (2))
read(2,*) x
if (x == max) then
x=999
k=k+1
endif
write(3,*) x
enddo
rewind(2)
rewind(3)
do while (.not. eof (3))
read(3,*) x
write(2,*) x
enddo
close(2)
close(3)
open(2, file=name, access='append')
write(2, *) k
close(2)
end subroutine
Пример.
В текстовом форматном файле хранится вещественная матрица, причем ее размер записан в первой записи. В остальных записях построчно хранятся элементы матрицы. Определить сколько столбцов в матрице равны первому. На экран вывести матрицу, количество столбцов, а также записать результат в текстовый файл.
В файле элементы матрицы можно располагать в порядке следования элементов по строкам (либо все элементы в одной строке файла, линейно, либо по 1 элементу в строке, либо каждая строка матрицы на отдельной строке в файле, если стоит неявный цикл ввода по строкам). Если при вводе в списке ввода нет неявного цикла ввода по строкам, то следует помнить, что элементы матрицы хранятся в памяти по столбцам и тогда, элементы матрицы вводятся в соответствующем порядке.
program main
implicit none
real, allocatable:: x(:,:)
integer col, row, kol, i, j, k
open (10, file='isx.txt', status='old', err=11)
read (10, *) row, col
!чтение из файла размера матрицы
allocate (x (row, col))
! чтение матрицы из файла
call read_matr (x, row, col)
close(10)
!вывод матрицы на экран
print*,'isx matr'
print '(<col> F3.0)', (( x(i,j), j=1,col), i=1,row)
!определение количества столбцов равных первому
k= kol (x, row, col)
print '(A, I2)', ' kol= ', k
call write_res (x,row,col,k)
stop
!oбработка ошибок
11 print*, ' oshibka open isx file'
end program
!считывание матрицы из файла
subroutine read_matr (x, n, m)
implicit none
integer,intent(in)::n, m
real,intent(out):: x(n, m)
integer i, j
read(10, *) (( x(i, j), j=1, m), i=1, n)!
end subroutine
integer function kol (x, n, m)
implicit none
integer,intent(in)::n, m
real,intent(in)::x(n, m)
integer i,j,k
logical f
k=0
do j= 2, m
f=.true.
do i= 1, n
if (x( i, j)/= x( i, 1))then
f=.false.
exit
endif
enddo
if (f)k=k+1
enddo
kol=k
end function
!запись в файл результата
subroutine write_res(x,n,m,k)
implicit none
integer,intent(in)::k,n,m
real,intent(in)::x(n, m)
integer i, j
open (20, file='res.txt', status='new', err=12)
write (20,'(A)'),'isx matr'
write(20, '(<m> F3.0)'), (( x(i,j), j=1,m), i=1,n)
write(20,'(A, I2,A)' ),'w matrice ',k,' stolb = perwomu'
close (20)
return
12 print*,'oshibka zapisi в файл'
end subroutine