Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
современный фортран , Бортеньев.pdf
Скачиваний:
242
Добавлен:
26.03.2015
Размер:
2.34 Mб
Скачать

9. Форматный ввод/вывод

Данные в памяти ЭВМ хранятся в двоичной форме, представляя собой последовательность нулей и единиц. С особенностями представления различных типов данных в ЭВМ можно познакомиться, например, в [5]. Употребляемые в Фортране модели данных целого и вещественного типа рассмотрены в разд. 6.11.1.

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

Стандартные средства Фортрана поддерживают 4 вида В/В данных:

форматный;

под управлением списка В/В;

неформатный;

двоичный.

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

В настоящей главе мы рассмотрим только два первых вида передачи данных: форматный и под управлением списка. Неформатный и двоичный В/В рассмотрены в гл. 10.

9.1. Преобразование данных. Оператор FORMAT

Перевод данных из внутреннего представления в текстовое задается

дескрипторами преобразований (ДП). Так, для вывода вещественного

числа на поле длиной в 8 символов, в котором 3 символа отведены для представления дробной части, используется дескриптор F8.3. Максимальное значение, которое можно отобразить на заданном поле, равно 9999.999, а минимальное - -999.999. Для преобразования внутреннего представления целого числа в текст длиной в 10 символов применяется дескриптор I10. Чтобы напечатать символьную переменную в поле длиной 25 знаков, применяется преобразование A25.

290

9. Форматный ввод/вывод

Дескрипторы преобразования содержатся в спецификации формата, например:

real :: a = -345.456

 

 

integer :: k = 32789

 

 

character(20) :: st = 'Строка вывода'

 

write(*, '(1x, f8.3)') a

!-345.456

write(*, '(1x, i10)') k

!

32789

write(*, '(1x, a25)') st

!

Строка вывода

 

 

Замечание. Символ

использован для обозначения пробела.

Спецификация формата включает заключенный в скобки список ДП. Спецификация может быть задана как встроенная в оператор В/В символьная строка, например:

'(F8.3, I10)'

или как отдельный оператор FORMAT, на который операторы В/В ссылаются при помощи метки. Общий вид оператора:

метка FORMAT (список ДП)

ДП разделяются в списке ДП запятыми. Например:

write(*, '(1x, f8.3, i10)') a, k

!-345.456

32789

write(*, 1) a, k

!-345.456

32789

1 format(1x, f8.3, i10)

 

 

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

Таблица 9.1. Символы управления кареткой печатающего устройства

Символ

Действие

Пробел

Начать новую строку

+Остаться на той же строке (перепечатать)

0

Пропустить одну строку

1

Перейти на начало следующей страницы

Поэтому первая позиция строки вывода на экране и печатающем устройстве не отображается.

Чтобы исключить генерацию ложных символов управления кареткой в FPS существует два средства:

291

О. В. Бартеньев. Современный ФОРТРАН

можно всегда вставлять при форматном выводе по крайней мере один пробел в качестве первого символа в каждую запись. Это выполняется дескриптором 1X или T2;

можно подсоединить внешнее устройство, задав в операторе OPEN

спецификатор CARRIAGECONTROL = 'LIST' (разд. 11.4). В этом случае первый символ каждой записи при форматном выводе не будет интерпретироваться как символ управления кареткой и будет выводиться на внешнем устройстве, например:

write(*, 1) 'abcd'

! bcd

open(6, carriagecontrol = 'list')

! по умолчанию устройство 6 - это экран монитора

write(*, 1) 'abcd'

! abcd

1format(a)

ВCVF по умолчанию CARRIAGECONTROL = 'LIST', поэтому предварять список ДП дескриптором 1X, если правила умолчания не изменены, нет необходимости.

Пример:

write(*, '(i3)') 123

! CVF:

123

end

! FPS:

23

Замечание. В DS есть возможность редактирования оператора FORMAT. Для этого установите курсор на оператор FORMAT, в котором есть хотя бы один ДП, и затем выполните цепочку Edit - Fortran Format Editor.

9.2. Программирование спецификации формата

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

Пример. Запрограммировать формат для вывода заголовка по центру экрана. Задачу решить, предполагая, что длина заголовка меньше ширины экрана.

Введем обозначения: tl - длина заголовка без завершающих пробелов; sl - ширина экрана (в текстовом режиме ширина экрана составляет 80 символов). Для центрирования заголовка необходимо отступить от левой границы экрана n = (sl - tl)/2 символов, а затем вывести заголовок. Так, при tl = 60 следует применить формат

'(11X, A)' или '(T12, A)'

а при выводе заголовка длиной в 40 символов подошел бы формат

'(21X, A)' или '(T22, A)'

292

9. Форматный ввод/вывод

Текст программы формирования формата вывода заголовка длиной tl:

program t2

character(78) :: title = 'Пример заголовка'

character(20) form

! Строка формата вывода

integer(1) tl, n, sl /80/

 

tl = len_trim(title)

! Длина заголовка без завершающих пробелов

n = (sl - tl) / 2

 

!Формирование формата вывода (строки fmt) с дескриптором X write(form, '(a, i2, a)') '(', n, 'x' // ',' // 'a' // ')'

!или в случае использования дескриптора T

!write(form, '(a, i2, a)') '(' // 't', n + 1, ',' // 'a' // ')'

write(*, form) title

! Вывод заголовка

end program t2

 

Пояснения:

1.Строка является внутренним файлом, при работе с которым используется форматный В/В.

2.Дескриптор Tn смещает позицию В/В на n символов вправо.

Замечания:

1.Задание формата '(nX, A)' или '(Tn, A)' является ошибкой, так как в этом случае дескриптор содержит недопустимый для формата символ n, вместо которого должна быть использована буквальная положительная целая константа без знака. Далее, правда, мы покажем, что такие целые константы могут быть заменены заключенным в угловые скобки целочисленным выражением (разд. 9.3).

2.На самом деле при выводе в DOS-окно заголовок, содержащий русский текст, будет выведен как нечитаемый набор символов. Чтобы поправить положение, необходимо использовать приведенную в прил. 1 функцию RuDosWin, принадлежащую модулю TextTransfer, и внести в приведенный выше код следующие изменения:

module TextTransfer

! Код модуля TextTransfer см. в прил. 1

...

end module TextTransfer

 

program t2

 

use TextTransfer

! Для вывода русского текста

character(78) :: title = 'Пример заголовка'

! Код программы t2 см. выше

...

write(*, form) trim(RuDosWin(title, .false.))

! Вывод заголовка

end program t2

 

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

293