Обмен данными в Фортране
Ввод-вывод в Фортране реализован средствами
языка, чего нет в Паскале и С, где вместо
этого используется набор внешних функций.
Структура оформляемого текста должна
соответствовать решаемой задаче. Текст
появляется в результате выполнения многих
операторов write, но каждый начинает вывод
с новой строки. Аналогично каждый read
начинает ввод с новой строки. В рамках одного write
или read используется только один
способ оформления текста, хотя в Фортране их
предусмотрено несколько.
Общая концепция
В компьютере идет двусторонний обмен данными
между двумя разными хранилищами
Внешняя
память на HDD |
<= write <=
|
RAM
при CPU |
=>
read => |
RAM - оперативная память при CPU, быстрая, но по
сравнению с HDD небольшая по объему - здесь
хранятся объявленные в программе объекты во
внутренней форме, характерной для каждого типа
данных и для каждого типа CPU. Важным моментом,
отличающим языки высокого уровня (Фортран,
Паскаль) от таких языков как С и Ассемблер,
является строгая типизация данных. Это означает,
что ни программист, ни тем более пользователь не
обязаны в тонкостях знать устройство и команды
компьютера. Программисты придерживаются
соглашений о типах в выбранном языке (Фортран,
Паскаль), а в технические подробности
преобразования во внутреннее представление
конкретного компьютера входит компилятор. В
таблице приведены для справки объемы
памяти (в *байтах) для объектов пяти базовых типов
данных Фортрана и их возможных разновидностей
для IBM/PC
Тип |
Разновидность
по умолчанию |
Возможные
разновидности |
Integer |
Integer
*4 |
*1 *2 *4 |
Real |
real*4 |
*4 *8 |
Complex |
Complex*8 |
*8 *16 |
Logical |
Logical*4 |
*1 *2 *4 |
Character |
Character*1 |
от *1 до
*32767 |
Внешняя память на жестком диске HDD имеет на
несколько порядков большую ёмкость, чем RAM, но она
и менее быстрая - здесь хранят файлы в рамках FS -
файловой системы ПК: FAT, FAT32, .. Приведем в таблице
соглашения об именах файлов для некоторых FS
Файловая система |
Имя.Расширение |
Алфавит
в имени файла |
FAT для DOS |
8.3 |
по
английски без пробелов |
FAT, FAT32
для Win-98, 2000, XP |
255.3 255 255.* |
по-русски
и по английски
c пробелами |
NTFS: Win-NT, 2000, XP |
Программист от лица CPU реализует обмен данными
с помощью операторов read и write.
Пользователь, общаясь с ПК по своей задаче,
разглядывает и редактирует те же
текстовые файлы, что и CPU.
пользователь |
<=просмотр
<= |
текстовые файлы
*.txt |
<=write
<= |
объекты
во
внутренней форме для CPU |
редактор<=
=> |
=>read
=> |
Текстовые файлы имеют расширение *.txt
для их просмотра на консоли и принтере и
для редактирования на консоли имеется масса
оболочек, навигаторов, эксплореров и редакторов.
Текстовые файлы это информативный вид файлов
для пользователя. Хороший программист исходит из
следующего
- существует разделение труда между
программистом и пользователем
- Фортран имеет гибкие средства для текстового
оформления данных и результатов
- проектируя обмен от лица CPU, хороший программист
должен занимать сторону пользователя,
представляя его интересы
- привлекателен GUI-графический интерфейс
пользователя, его реализация требует
использования внешних функций
- MS имеет библиотеки низкоуровневой
графики и адаптации к среде WINDOWS
- для поддержки реалистической графики
используют надязыковые библиотеки OpenGL
- внешние библиотеки применимы в тех языках, для
которых есть интерфейсы
Аналогия последовательного обмена с
кассетным магнитофоном
Последовательный ввод-вывод легче понять,
используя аналогию с кассетным магнитофоном
Кассетный
магнитофон |
Последовательный обмен данными |
может
быть несколько дек 1,2 |
Устройство ввода-вывода - 0,1,2,..
константы или переменные целого типа |
Кассета
с магнитной лентой |
Последовательный файл |
Возможно
чтение и запись |
Операторы read и write |
Кассета
надписана |
Файл назван file=’имя’ |
Вставить/Извлечь
кассету в/из деки |
Открыть/Закрыть файл
open(u,file=’имя’ ) / close(u) |
Пишут-читают
песню за песней там, где магнитная головка |
Пишут-читают файл последовательно
с текущей позиции |
Писать
можно только "в хвост" ленты |
пишут только в конец файла |
Перемотать
в начало (Rewind)/конец |
Rewind(u) / Endfile(u) |
Вернуться
назад на песню |
Вернуться назад на запись Backspace(u) |
Узнать
имя кассеты или деки |
Узнать имя/ номер
Inqure(u..)
Inqure(file=’имя’..) |
Оператор обмена данными обмен (
КУДА, КАК ) ЧТО дает ответы на 3
вопроса
|
КУДА / ОтКУДА |
|
КАК |
|
ЧТО |
read( |
Из
текстового файла
№ |
,
===> |
по
типам
объектов |
)
===>
|
Список
объектов
в
RAM |
write( |
В
текстовый файл
№ |
,
<=== |
)
<=== |
Ответы на вопросы “КУДА”, “КАК”, “ЧТО”
оформляются в виде операторов
- read (отКУДА,КАК) ЧТО
- write (КУДА , КАК) ЧТО
В целом ответы на эти вопросы должны прояснить
следующее
- ЧТО за список объектов, подлежащих
обмену с внешней памятью
- ОТКУДА/КУДА – каков номер устройства –
ответы см КУДА
- “КАК” – задает способ оформления
вводимых-выводимых объектов в виде текста,
способы для ввода (данные в файле готовит
пользователь) и вывода (результаты в файл пишет
компьютер) похожи; см. возможные ответы КАК
Обсудим поподробнее возможные ответы, давая
каждый раз ответ только на один из трех вопросов.
Будем иметь в виду, что в реальном операторе
ввода-вывода будут сочетаться возможные ответы
на каждый из трёх вопросов.
Ответы на вопрос "ЧТО" в
операторе обмен(
КУДА, КАК ) ЧТО
ЧТО - это список объектов,
подлежащих обмену с внешней памятью. В него могут
входить
- в список “ЧТО” для Read - переменные через
запятую
- в список “ЧТО” для write – переменные,
константы и формулы через запятую
- переменные могут быть как скалярными, так и
векторными (массивами и сечениями массивов)
- формулы в Фортране-90 также могут быть
векторными
Ответ на вопрос “ КУДА / ОтКУДА?”
Ответ на этот вопрос характеризует носитель
информации и направление ввода-вывода
текстового файла. Основополагающим является
принцип независимости от носителя информации и
физической природы устройств. В программе имеют
дело с условными устройствами, которым
различными способами сопоставляются конкретные
физические устройства, например, консоль, экран,
принтер, магнитная лента, файл на жестком диске,
файл на дискете, файл на магнитной ленте..
Предопределенные номера устройств и имена
файлов
Консоль – это рабочее место пользователя ПК,
особое устройство, всегда готовое и не
требующее открытия файла. Консоль включает в
себя клавиатуру для ввода по команде read и
экран для вывода по команде write
Для консоли в Фортране исторически
сложились следующие обозначения
- * - универсальный знак консоли для ввода read(*,.. и
вывода write(*,..
- 0 – то же в виде номера для ввода read(0,.. и
вывода write(0,..
- 5 – только для ввода с клавиатуры read(5..
- 6 - только для вывода на экран write(6..
Номера 5 и 6 по усмотрению программиста можно
переназначить в операторе open.
Имеется ряд имен файлов, фиксированных
по назначению в ОС
- con – консоль
- prn – принтер
- line – линия связи
- nul – пустышка, вывод в никуда
При открытии файлов у программиста есть ряд
возможностей
- устройства 0,5,6 и “*” ориентируют без открытия
файла на работу с консолью
- open(u,file=’имя.txt’) связывает условный номер
устройства с конкретным файлом
- имена файлов “con”, “prn”, “line”, “nul” организуют
обмен с конкретным физическим
устройством
- можно, опустив open, отнести открытие файла к
компетенции пользователя, отложив его до
выполнения программы
если, скажем для устройства 3, нет оператора open
или open есть но file=’ ’, то на первой
команде обмена последует сообщение
Unit 3 – file name missing or blank
|
имя файла пустое или не задано |
Please enter file name |
пожалуйста введите имя файла |
в
ответ пользователь введёт имя файла, с которым
далее и пойдет обмен |
- использовав строковую переменную
вместо номера устройства будем иметь дело с так
называемым внутренним файлом, не требующим
открытия, например, для
Real :: R=2.0, pi=3.14; Character*80 stroka; Write(stroka,*)
‘c:’,2*pi*R
! получим stroka = “ c:6.2800000 “
отметим, что строка должна быть достаточно
вместительной, многострочный вывод направляют в
массив
часто так готовят тексты для графического вывода
- имеются и описаны в помощи дополнительные
параметры, повышающие функциональность
оператора open
Ответы на вопрос "куда/откуда" в операторе обмен( КУДА, КАК ) ЧТО
сведены в таблицу
Возможные
ответы |
Направление
обмена данными |
Открытие
файла |
или 0 или
5 или 6 |
с
консолью |
не
требуется |
Номер
устройства |
с
открытым файлом |
выполняется
до обмена в open |
Номер
устройства |
когда
файл не открыт |
выполняется
пользователем при первом обмене |
Строка |
со
строкой
(внутренним файлом) |
не
требуется |
Ответы на вопрос “ КАК?” в операторе
обмен( КУДА, КАК ) ЧТО
Ответы на этот вопрос должны прояснить способ
преобразования данных между внутренним
представлением компьютера и текстовым
оформлением в файле. Психология пользователя
такова, что при оформлении текста у него
диаметрально противоположные требования
- он предпочитает минимум забот по оформлению,
когда он должен готовить данные
- он требует, чтобы все было четко, понятно,
прокомментировано, когда ему выводят
результаты
- правила оформления одни и те же, что при вводе,
что при выводе, поэтому надо программировать
разные способы в read и write
Рассмотрим возможные способы оформления
текста, а затем дадим рекомендации по их
использованию.
Ответы на вопрос “ КАК?” в операторе
обмен( КУДА, КАК ) ЧТО сведены в таблицу
|
Ответ КАК |
Способ преобразования данных |
Где ответ на вопрос КАК? |
1 |
* |
ввод-вывод под управлением списка |
по типам данных из списка
"ЧТО" |
2 |
имя |
Вместо
ЧТО поименный обмен по списку
переменных из Namelist |
по
типам данных из списка Namelist |
3 |
метка |
Форматный ввод-вывод cо ссылкой
на
m format
ФС |
в ФС в виде строковой константы
в операторе m format ФС |
4 |
строка |
Форматный ввод-вывод по ФС,
прописанной внутри write |
в ФС в виде константы, переменной
или выражения типа character |
5 |
опущен |
обмен с бинарным файлом без
всяких преобразований |
не нужен ответ |
КАК оформляется текст при вводе и выводе
разными способами
- ввод-вывод под управлением списка read (отКУДА,*
) ЧТО и write (КУДА , * ) ЧТО
этот способ оформления текста особенно удобен
при вводе - все делается по усмотрению
пользователя: перенос, пробелы и пустые
строки; он сам выбирает разделитель между
числами и строками ( “запятая”, “пробел” или
“Enter-конец строки”), строки обрамляются
апострофами; в то же время это довольно
небрежный, скорее черновой вывод в виде
стандартизованного текста с фиксированной
шириной листа и полей чисел; вывод идет по списку
“ЧТО” с автоматическим переносом
- поименный ввод-вывод по списку переменных
из Namelist, совмещающему ответ на вопросы “КАК”
и “ЧТО”, списка “ЧТО” нет
- в примере переменным x,R дано
групповое имя в Namelist /listXR/ x,R; Read
(*,listXR ); write (*,listXR)
- текст стандартизован, но в отличие от п.2, в нем
есть имя списка и отдельных переменных
- вывод скорее всего черновой - идёт с
автоматическим переносом по списку из Namelist с
фиксированной шириной полей чисел и листа
ввод в любом порядке |
даже и не все |
& listXR |
|
& listXR |
|
& listXR |
x=3.2, R=2.5 |
|
R=2.5,x=3.2 |
|
x=3.2 |
/ |
|
/ |
|
/ |
3. Форматный ввод-вывод дает наиболее гибкий
исчерпывающий ответ на вопрос “КАК” в виде
форматной строки (ФС) в отдельном операторе
m FORMAT ФС , здесь ФС- строковая константа
без апострофов; на ФС можно сослаться из
многих операторов вывода по метке m
4. Форматный ввод-вывод с уникальной ФС
прямо внутри операторов Read (отКУДА, ФС
) ЧТО и write (КУДА , ФС ) ЧТО
здесь ФС- константа, переменная или
выражение строкового типа (character)
5. Ввод-вывод, отображающий память - ответ на
вопрос “Как?” опущен и не нужен
Read (отКУДА) ЧТО и write (КУДА)
ЧТО ведут обмен данными с бинарным файлом
Резюме по способам ввода-вывода
- данные при вводе оформляются аналогично
тому как они оформляются при выводе, разве что не
пишут незначащие цифры
- форматный вывод дает наибольшие
возможности по оформлению текстов
- вывод под управлением списка и поименный
вывод удобны при черновом выводе
- ввод под управлением списка устроит
"ленивого" пользователя, не связывая его
ограничениями
- поименный ввод может оказаться удобным,
когда при повторном вводе из многих данных мало
что меняется
- форматный ввод имеет ограниченное
применение, например, для компьютерных форм;
данные размещаются позиционно, без разделителей,
строковые данные выделять апострофами не надо.
Форматный вывод
Форматный вывод дает исчерпывающие
возможности по оформлению текстов. Форматный
вывод так хорошо продуман, что за 50-летнюю
историю Фортрана существенно не изменился.
Форматный вывод сложнее вывода стандартных
текстов, поэтому изложим его описание
неформально и формально.
Format – неформальное описание
Неформальное описание – это 4 идеи
- Идея 1 write закодированные в
памяти объекты превращает в понятный текст
- Идея 2 Ручка и Бланк
Write и Format
- Идея 3 правило таблицы – одним Write можно
напечатать целую таблицу
- Идея 4 format пишется математически
точно, почти как формула
Идея 1 write закодированные
объекты превращает в текст
Оператор write относительно
вывода дает ответ на 3 вопроса
Write( куда ,
как ) что |
Куда выводить - текстовый
файл – доступен для чтения человеком |
Как оформить выводимую
информацию
FORMAT |
Что выводить - список объектов в
порядке вывода |
основная
характеристика ширина текстового поля c w e |
описатель (дескриптор)
обозначается одной буквой и точно соответствует
по типу объекту |
объекты закодированы в памяти
компьютера по типам |
Описатель превращает закодированные
объекты в текст |
сканируется
список дескрипторов и запрашиваются объекты из
списка “ что ” |
Объекты раскодируются по мере
поступления из списка Что |
-39 здесь i3 |
Целое число
c
Iw c |
Integer |
-0.00076 здесь f8.5 |
Фиксированная форма вещественного числа
c Fw.d
c |
Real
например
-0.7654321e-3 |
-0.76e-03 здесь E9.2 |
Экспоненциальная форма вещественного числа
c Ew.d
c |
(-0.76e-03, 0.12e+00) здесь 2E9.2 |
c 2Ew.d c |
Complex
(
-0.7654321e-3, 0.1234567 ) |
T F
здесь L1 |
c Lw c |
Logical |
абрака
здесь A6 |
c Aw c |
character
например
‘абракадабра’ |
абракадабра
- вся строка целиком |
c A c |
Дескрипторы должны строго соответствовать объектам
по типам, но совсем не обязательно объектов и
дескрипторов должно быть поровну
- объектов и дескрипторов поровну – это
наиболее простой вариант
- мало объектов – много дескрипторов –
просто в одной из ссылок на Format
из нескольких Write не все
дескрипторы будут использованы
- много объектов– мало дескрипторов –
работает правило таблицы – см. Идея 4
Идея 2 Ручка и Бланк
Write и Format
Люди придумывают всевозможные бланки, чтобы
упростить оформление сложного текста.
Окончательный текст как бы разнимается на две
части и формируется
- из текста бланка, его аналог в программе –
это Format;
неизменная часть текста, надписи пробелы,
графления и поля подходящего типа для заполнения
данными из списка “ что ” – такова структура
бланка
- из текста, вписываемого в зарезервированные
поля ручкой, ее аналог в программе – это Write, точнее
объекты из списка “ что
”
Пример из телефонного бланка
ФИО абонента
название улицы
__________
______________
200_ г
всего _______
Заполненный бланк
ФИО абонента
название улицы
Звягин В.Ф.
Серебристый
2004 г
всего 212.57
Операторы вывода для этого примера
write (*,2000) ‘Звягин В.Ф’, ’Серебристый’,4,
212.57
2000 format(‘ФИО абонента’,4x,’название улицы’/ a,
4x,a/ ‘200’ ,i1/ 15x,’всего’ , F7.2)
Как в формате выполняется оформление при
выводе
- “,”- запятая соединяет поля одной строки в
единый текст
- “/”- слэш разъединяет строки
выводимого текста
- 4x – в этом месте 4 пробела
- ‘ФИО абонента’ – в
этом месте такая надпись
Перечисленные оформительские дескрипторы
исполняются попутно по мере перекодирования
объектов дескрипторами данных.
Какие из надписей отнести к бланку, а какие
вписывать – это ответ на вопрос
- “Есть ли смысл эту надпись каждый раз
вписывать в бланк?”
Идея 3 правило таблицы
Правило таблицы работает автоматически,
если об этом не знать могут быть неприятные
сюрпризы.
Когда автоматически включается в работу
правило таблицы?
Если много данных – мало
дескрипторов write (*,
мало) много, то
Format
позволяет оформлять таблицы по следующим
правилам
- малое число дескрипторов - это число
колонок таблицы
- много объектов - это общее количество данных
в таблице
- много / мало - это число строк в таблице
- мало - это участок сканирования - он
заключает в скобки все или часть дескрипторов
- участок сканирования просматривается
многократно, потенциально бесконечно
повторяется
всё, если нет внутренних скобок Format(<=всё=>
)
повторяется часть, если есть
внутренние скобки;
часть- это показанная крупно последняя пара
внутренних скобок Format( (..)....(<=часть=>)
)
- несколько write(*,m) с разным
количеством данных, ссылаясь по m
на один и тот же m Format() ,
порождают таблицы, одинаковые по
ширине, но разные по высоте
По расположению участка сканирования и
полученному результату различают
- таблицу без заголовка - по Format( ..
) без внутренних скобок
участок сканирования - скобки (<=>
)
- таблицу с заголовком - по Format(
....=заголовок=>….(<==> ) ) с внутреними
скобками
заголовок просматривается однократно
скобок - сколько угодно, но участок
сканирования- это последняя пара внутрених
скобок, с повтоителем, если он есть
Пример
Не изменяя format, можно
получить два заполненных бланка, если дать вдвое
больше данных
write (*,2000) ‘Звягин В.Ф’, ’Серебристый’,4,
212.57, ‘Cавин
Ю.А.’,’Невский пр.’, 2 ,
1314.37
2000 format(‘ФИО абонента’,4x,’название улицы’/ a,
4x,a/ ‘200’ ,i1/ 15x,’всего’ , F7.2)
Не изменяя format, можно
получить три заполненных бланка, если дать втрое
больше данных, и т.д.
Идея 4 format пишется
математически точно, почти как формула
Подряд f8.5, f8.5, f8.5 проще пишется
как 3 f8.5
Подряд f8.5, i3, f8.5, i3, f8.5,
i3, f8.5, i3 проще пишется как
4( f8.5, i3 )
Исключения из правил
- 1x - пишется всегда с
повторителем, хотя обычно повторитель 1 опускают
- 25(’=’) - повторитель для надписи пишется
всегда со скобками, хотя обычно скобки нужны,
если повторяют группу дескрипторов
Как и в формуле, можно использовать скобки
свободно, но не надо забывать про участок
сканирования и правило таблицы, срабатывающее
автоматически.
Несколько write могут
ссылаться на один и тот же format,
если ответ на вопрос “как?” один и тот же.
В Фортране имеется 4 способа переноса строк
- каждый write, не только
форматный, начинает вывод с новой строки, хотя
может напечатать и несколько строк
- слэш ‘/’ в формате переносит строку
- повторение участка сканирования автоматически
начинает вывод с новой строки
- неформатный вывод делает перенос строк
автоматически по стандартной ширине листа, а Вы
лишь косвенно управляете этим, давая больше или
меньше объектов на вывод
Format – формальное описание
Ответ на вопрос КАК дается в виде ФС. Ответ
настолько точен и лаконичен, что ФС- это почти что
формула. Обсуждается состав ФС, правописание,
интерпретация. Один write может
выводить много строк, но лишь форматный вывод
даёт полный контроль над переносом, в других
способах перенос только автоматический и
неряшливый. Во многих write можно
сослаться на один и тот же format,
дав один и тот же ответ на вопрос КАК. Вывод таблицы
как наиболее общей текстовой структуры прописан
правилами форматного вывода. Неповторяющийся
текст или таблица без шапки - частные случаи.
Внутри ФС нет указания на число строк
таблицы, их число любое в зависимости от данных.
Рассматрим следующие вопросы
- как данные разных типов преобразовать в
текст
- как компактно записать ФС
- как сделать текст выразительным
- каков результат взаимодействия списков КАК и
ЧТО
Состав ФС - это список
дескрипторв (..s), заключенный в скобки.
Дескрипторы в списке ..s разделены знаками
, / \ : Перед
дескриптором или группой дескрипторов
в скобках можно писать повторитель. В ФС
всегда имеется единственная пара скобок, которая
образует участок сканирования.
Дескрипторы подразделяются на 4 категории
- I,F,E,D,A,L - дескрипторы преобразования
данных по типам
- G,Z,O,B - универсальные дескрипторы
преобразования данных любого типа
- управляющие дескрипторы, видоизменяющие вывод
чисел, а именно:
SP,SS,S-выводить
ли "+"
какого порядка мантисса
сколько цифр в порядке, например, 3P
и т.п.- подробности в помощи
- оформительские дескрипторы делают текст
более выразительным
'надписи' или "надписи
с 'апострофами' в тексте
" или 'надписи с
"кавычками" в тексте '
X - вывод пробелов - 5X-пять пробелов
T- смещения в строке - T5-в 5-ю позицию, TR6-6
позиций вправо, TL7 - 7 позиций влево
“,” – запятая соединяет текстовые поля
внутри строки
“/” - разделяет текст на строки
“:” – двоеточие останавливает просмотр
дескрипторов, если данные закончились
"\" - блокирует перенос
Дескрипторы преобразования объектов в
текстовые поля по типам
тип |
форма
вывода |
пример |
выбор
из |
integer |
целое
число |
_ _-31 |
I |
вещественные
числа
real
double precision
или real*8 |
фиксированная
форма |
_ _-0.0025 |
F
E |
экспоненциальная
форма |
_ _-0.25e-02 |
двойной
точности |
_ _-0.25d-002 |
D |
Character*целое |
строка |
литмо_ _ _
или O’K_ _ _ |
A A20 |
logical |
логическая
величина |
_ _F |
L |
complex |
комплексное-пара
вещественных |
(2.1,-3.1) |
два
по F E D |
Примечание: числа прижаты к правому краю
поля, а строки - к левому краю поля
Повторители и участок сканирования ФС
- допускается повторитель перед отдельным
дескриптором, повторитель "1" не пишут,
например 3F5.2 вместо F5.2,F5.2,F5.2
- дескриптор X пишется только с
повторителем, даже 1X
- повторяющаяся надпись, пишется всегда в
скобках, даже с единственным символом, как в
7('*' ) вместо '*******'
- допускается повторитель группы дескрипторов в
скобках, - пишут 2( 2X, G9.2) вместо 2X,
G9.2, 2X, G9.2
- участок сканирования - ниже в обоих примерах -
это (i4, f5.2 )
- либо вся ФС без скобок внутри, как в
format (i4, f5.2 )
- либо пара скобок перед последней скобкой
ФС, как в format( 2x,'таблица'/
(i4, f5.2 ) )
- повторитель в Ф-77 - константа; в Ф-90 - еще и целое
выражение в угловых скобках, например
<2*N+1>F5.2
Трудный пример: 5 format ( // '
заголовок'/ 2( f7.3, 4x ) ) - описывает таблицу с двумя
колонками данных и любым числом строк.
Правила написания ФС
Format-это синоним "форматная строка,
записанная в специальном операторе".
Format - это оператор описания, хотя
размещается в любом месте программы.
Оператор m format(..s) пишут с меткой, чтоб на него
ссылались многие write( куда , m )
ЧТО
Общие правила
- ФС внутри write(КУДА,ФС) ЧТО может быть
строковой
константой c обрамляющими кавычками write(
7 , "( 'f=', F5.2 )" ) F
строковой переменной, которая должна бать
вычислена заранее и построена по всем
правилам оформления ФС,
как, например, real F; character*11
FS; FS="( 'f=', F5.2 )"; write( 7 ,
FS ) F
здесь FS упоминают в качестве формата write(
7 , FS ) F
меткой оператора format; ФС в операторе format
пишется без обрамляющих апострофов
на метку можно сослаться из одного или
нескольких write по метке
real X,Y; write( 7 ,
5 ) X,Y; 5 format(F5.2,
2X, G9.2)
- ФС всегда заключают в наружные скобки -
('f=',G9.2)
- в любой ФС однозначно
определяется участок сканирования, подробности
ниже
- допускаются разделители, повторители, скобки,
вложение скобок неограниченно
- за дескриптором данных I,F,E,D,L,A,G,Z,O,B следует
ширина поля, например i4;
исключение - A-дескриптор строки,
которая выводится целиком
- за шириной вещественного поля F, E, D
указывают сколько цифр после точки, как "2" в F5.2
- за шириной вещественного G указывают
сколько значащих цифр числа выводить, как "3"
в G10.3 ;
поле G автоатически оформляется как F или E
в зависимости от порядка
- дескриптор E, D указывает букву порядка и
сколько за ней цифр (для e-две и для d-три)
Правила для участка сканирования
- участок сканирования есть в любой ФС и
определяется однозначно
- либо вся форматная строка format(..) когда внутри ФС скобок
нет
- либо пара скобок перед последней скобкой форматной
строки format( ..(..))
- не пишут дескрипторы между двумя последними
скобками ФС
format( // ' заголовок'/
( i2, 2f7.2) ,5x,i2 ) - в данном примере
до ,5x,i2 просто
никогда не дойдут
- повторитель перед участком сканирования - это не
число строк, а, как обычно, число групп полей в
строке таблицы
- механизм сканирования включается
автоматически, когда данных больше, чем
дескрипторов данных
- вывод таблицы с любым чисом строк
порождается многократным просмотром участка
сканирования
Система форматного вывода
Система ввода-вывода
встраивается в исполняемый модуль. Наличие в
программе лишь одного write подключает всю
систему ввода-вывода, в то же время большее число
команд ввода-вывода добавляет только вызовы того
же самого интерпретатора. Каждая ФС хранится в
исполняемом модуле или вычисляется им, но в любом
случае интерпретируется этой системой. При
форматном выводе одновременно стартуют,
а потом синхронно продвигаются три списка
- [1] список дескрипторов из ФС - однократно начало
и многократно на участке сканирования
- [2] список объектов из ЧТО от начала до конца
- [3] текстовые поля складываются в строки, строки
образуют текст
- текстовые поля данных разбавляются надписями и
пробелами из оформительских дескрипторов
- числовые поля видоизменяются под воздействием
управляющих дескрипторов
- не требуется, чтоб ФС и список ЧТО были одной
длины, но обязательно соответствие по типам при
их синхронном просмотре
Механизм форматного вывода
- основан на принципе интерпретации, то есть на
разборе ФС во время исполнения программы
- ФС контролируется всегда по одним и тем же
правилам, независимо от происхождения ФС
- ФС, записанная в format, контролируется
предварительно при компиляции и во время
исполнения
- ФС-константа, записанная непосредственно
внутри write, контролируется только во время
исполнения
- ФС-переменная, упомянутая в write, должна
быть вычислена до этого, контролируется только
во время исполнения
- ФС и список вывода write должны быть
согласованы по типам данных - надо быть особенно
внимательным при сканировании
- Ваша беда, если Вы не знаете, что механизм
сканирования запускается автоматически, как
только данных больше, чем дескрипторов данных
Распределение текста по строкам с помощью
разделителей и механизма сканирования
- однократный просмотр начала ФС, многократный
просмотр участка сканирования, пока есть данные
- если список вывода короче списка
дескрипторов, то, не досмотрев дескрипторы, вывод
оборвется по концу данных
- если список вывода длиннее списка
дескрипторов, то вывод оборвется по концу данных
в процессе сканирования
- встретившийся разделитель ":" оборвет
просмотр и исполнение оформительских
дескрипторов, если список ЧТО исчерпан
- встретившаяся запятая продолжит вывод в той же
строке текста
- встретившийся "/"-слэш вызовет
переход к следующей строке текста
- возврат по сканируемому участку вызывает
переход к следующей строке текста
- встретившийся разделитель "\"-обратный
слэш блокирует переход к новой строке текста
- ФС ( ..s (..t ) )
оформляет таблицу - ..s- формат шапки таблицы,
..t – формат строки таблицы с
любым числом строк
- ФС с единственной парой скобок (..t)
создаст таблицу без шапки с любым числом строк
- ФС ( ..s ) оформит не таблицу, а просто
текст, если данные не повторяются многократно
- разбор дескриптора данных породит
запрос в список ЧТО и оформит текстовое поле
в текущей строке
Трудный пример - повторитель
группы дескрипторов в скобках перед участком
сканирования
- 5 format ( // ' заголовок'/ 2( f7.3, 4x ) ) -
описывает таблицу с двумя колонками данных
и любым числом строк
- 5 format ( // ' заголовок'/ (2( f7.3, 4x )) ) –
специально выделен скобками участок
сканирования (2( f7.3, 4x )) и потому формат более
очевиден по составу
Разбор и исполнение дескриптора
данных при интерпретации
- запрос по дескриптору данных может быть
исполнен,
если имеется очередной объект, если он
допустим по типу и если объект умещается
в отведенное поле
- универсальный дескриптор Z O B формирует
текстовое поле единообразно по
числу байтов каждого типа данных, см.
подробности в помощи
- универсальный дескриптор G формирует
текстовое поле в зависимости от типа данных, см.
подробности в помощи
- объект, не совместимый по типу с I F E
D A L, вызывает аварийное сообщение и останов
программы
- объект не строка, не умещающийся в отведенное
поле, заполняемое звездочками *****, вывод
продолжается
- дескриптор A без указания ширины поля
выводит строку целиком
- дескриптор A с шириной поля либо
добавляет недостающие пробелы справа либо
усекает строку справа
Приведем 2 простых примера для a=0.0000000, fault=-3.142859,
big= -128.1234; i=-12, k=321
1) аварийное завершение задачи
real a,fault, big; integer i, k
write(*,1) i,a, fault ; 1 format( 'целое=',
i4,3x, 'вещественное=', f6.2 )
В ФС 5 полей, из них 3 оформительских и 2
дескриптора данных i4 и f6.2. В списке вывода 3
переменных - i,a, fault. Внутри ФС нет
скобок, поэтому участок сканирования - вся ФС.
Сканирование действительно будет, так как
дескрипторов данных 2 меньше чем переменных -3.
При повторном просмотре ФС на запрос о целом поле
i4 попадает не совместимая по типу вещественная
fault. Последует сообщение expected
descriptor E, F or G for REAL - ожидается дескриптор
E F или G для вещественного числа - задача
снимется.
2) нормальный вывод двух пар переменных в две
строки при той же ФС; сканирование будет, так как
дескрипторов данных 2<4 переменных
write(*,1) i,a, k,big
- надпись 'целое=', запрос под i4 целой
переменной i ; 3 пробела, надпись
'вещественное='; запрос под f6.2
вещественной a
целое=_-12_ _
_вещественное=_ _0.00
1
2 3 4
5 <==
номера полей в строке
- ФС закончится, а данные еще есть - возврат по ФС
вызовет переход ко 2-ой строке текста
надпись 'целое=', запрос под i4 целой k ;
3 пробела, надпись 'вещественное='; запрос под
f6.2 вещественной good
целое=_321_ _
_вещественное=****** <= знак
big не влез в отведенные 6 позиций
1
2 3
4 5
<== номера полей в строке
- вывод прекратится, так как данных больше нет