Обмен данными в Фортране
Ввод-вывод в Фортране реализован средствами языка, чего нет в Паскале и С, где вместо этого используется набор внешних функций. Структура оформляемого текста должна соответствовать решаемой задаче. Текст появляется в результате выполнения многих операторов write, но каждый начинает вывод с новой строки. Аналогично каждый read начинает вывод с новой строки. В рамках одного write или read используется только один способ оформления текста, хотя в Фортране их предусмотрено несколько.
Общая концепция
В компьютере идет двусторонний обмен данными между двумя разными хранилищами
Внешняя память на HDD |
<= write <=
|
RAM при CPU |
=> read => |
RAM - оперативная память при CPU, быстрая, но сравнительно небольшая по объему - здесь хранятся объявленные в программе объекты во внутренней форме, характерной для каждого типа данных и для каждого типа 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 для их просмотра и редактирования имеется масса оболочек, навигаторов, эксплореров и редакторов. Текстовые файлы это самый информативный вид файлов для пользователя. Хороший программист исходит из следующего
- существует разделение труда между программистом и пользователем
- Фортран имеет гибкие средства для текстового оформления данных и результатов
- проектируя обмен, программист занимает сторону пользователя
- привлекателен 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 => |
по типам объектов |
=> read=>
<=write<= |
Список объектов в 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” организуют обмен с конкретным физическим устройством
- можно отнести открытие файла к компетенции пользователя, отложив его до выполнения программы
если, скажем для устройства 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( куда , как ) что |
Куда выводить - текстовый файл – доступен для чтения человеком |
Как оформить выводимую информацию |
Что выводить - список объектов в порядке вывода |
основная характеристика ширина текстового поля
ç w è |
описатель (дескриптор) обозначается одной буквой и точно соответствует по типу объекту |
объекты закодированы в памяти компьютера по типам |
Описатель превращает закодированные объекты в текст |
сканируется список дескрипторов и запрашиваются объекты из списка “ что ” |
Объекты раскодируются по мере поступления из списка Что |
-39 здесь i3 |
Целое число
ç Iw ç |
Integer |
-0.00076 здесь f8.5 |
Фиксированная форма вещественного числа
ç Fw.d ç |
Real
например
-0.7654321e-3 |
-0.76e-03 здесь E9.2 |
Экспоненциальная форма вещественного числа
ç Ew.d ç |
(-0.76e-03, 0.12e+00) здесь 2E9.2 |
ç 2Ew.d ç |
Complex
( -0.7654321e-3, 0.1234567 ) |
T
F здесь L1 |
ç Lw ç |
Logical |
абрака здесь A6 |
ç Aw ç |
character
например
‘абракадабра’ |
абракадабра - вся строка целиком |
ç A ç |
Дескрипторы должны строго соответствовать объектам по типам, но совсем не обязательно объектов и дескрипторов должно быть поровну
- объектов и дескрипторов поровну – это наиболее простой вариант
- мало объектов – много дескрипторов – просто в одной из ссылок на 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 позволяет оформлять таблицы по следующим правилам
- малое число дескрипторов - это число колонок таблицы
- много объектов - это общее количество чисел в таблице
- много / мало - это число строк в таблице
- все или часть дескрипторов на участке сканирования просматриваются многократно, потенциально бесконечно
- участок сканирования заключается в скобки
- несколько write, ссылаясь на один и тот же Format с разным количеством чисел, порождают таблицы с разным числом строк, но с одинаковым количеством колонок
По расположению участка сканирования и полученному результату различают
- таблицу без заголовка, порождаемую Format( .. ) , в котором нет никаких скобок, кроме скобок формата - эти скобки формата ç== и дают участок сканирования
- таблицу с заголовком, порождаемую форматом, в котором сколько угодно скобок, кроме скобок формата Format( ....=заголовок=>….(==> ) )
заголовок просматривается однократно ç== участок сканирования- это последняя пара скобок непосредственно внутри формата
Пример
Не изменяя format, можно получить два заполненных бланка
write (*,2000) ‘Звягин В.Ф’, ’Серебристый’,4, 212.57, ‘Cавин Ю.А.’,’Невский пр.’, 2 , 1314.37
2000 format(‘ФИО абонента’,4x,’название улицы’/ a, 4x,a/ ‘200’ ,i1/ 15x,’всего’ , F7.2)
Идея 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, если ответ на вопрос “как?” один и тот же.
В Фортране имеется 3 способа переноса строк
· каждый write и не обязательно форматный начинает вывод с новой строки, хотя может напечатать и несколько строк
· слэш ‘/’ в формате переносит строку
· повторение участка сканирования начинает вывод с новой строки
Неформатный вывод делает перенос строк автоматически, Вы лишь косвенно управляете этим
- давая больше или меньше объектов на вывод
- каждый write начинает вывод с новой строки
Format – формальное описание
Ответ на вопрос КАК дается в виде ФС. Ответ настолько точен и лаконичен, что ФС- это почти что формула. Обсуждается состав ФС, правописание, интерпретация. Один write может выводить много строк, но лишь форматный вывод даёт полный контроль над переносом, в других способах перенос автоматический и неряшливый. Во многих write можно сослаться на один и тот же format, дав один и тот же ответ на вопрос КАК. Вывод таблицы как наиболее общей текстовой структуры прописан правилами форматного вывода. Неповторяющийся текст или таблица без шапки - частные случаи. Внутри ФС нет указания на число строк таблицы, их число любое в зависимости от данных. Рассматрим следующие вопросы
- как данные разных типов преобразовать в текст
- как компактно записать ФС
- как сделать текст выразительным
- каков результат взаимодействия списков КАК и ЧТО
Состав ФС - это список дескрипторв (..s), заключенный в скобки. Дескрипторы в списке ..s разделены знаками , / \ : Перед дескриптором или группой дескрипторов в скобках может быть записан повторитель. В ФС всегда имеется единственная пара скобок, которая образует участок сканирования.
Дескрипторы подразделяются на 4 категории
- I,F,E,D,A,L - дескрипторы преобразования данных по типам
- G,Z,O,B - универсальные дескрипторы преобразования данных любого типа
- управляющие дескрипторы, видоизменяющие вывод чисел: SP,SS,S-выводить ли "+"; какого порядка мантисса, сколько цифр в порядке и т.п.- подробности в помощи
- оформительские дескрипторы делают текст выразительным
- 'надписи' или "надписи с 'апострофами' в тексте " или 'надписи с "кавычками" в тексте '
- вывод пробелов - 5X-пять пробелов
- смещения в строке - T5-в 5-ю позицию, TR6-6 позиций вправо, TL7 - 7 позиций влево
- “,” – запятая соединяет текстовые поля внутри строки
- “/” - разделяет текст на строки
- “:” – двоеточие останавливает просмотр дескрипторов, если данные закончились
Дескрипторы преобразования объектов в текстовые поля по типам
тип |
форма вывода |
пример |
выбор из |
integer |
целое число |
_ _-31 |
I |
вещественные числа
real
double precision
или real*8 |
фиксированная форма |
_ _-0.0025 |
F |
экспоненциальная форма |
_ _-0.25e-02 |
E |
двойной точности |
_ _-0.25d-002 |
D |
Character*целое |
строка |
литмо_ _ _
или O’K_ _ _ |
A |
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
- в специальном операторе format ФС пишется без обрамляющих апострофов - format(F5.2, 2X, G9.2)
- ФС всегда заключают в наружные скобки - format ( 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-три)
- ФС внутри write(КУДА,ФС) ЧТО может быть переменной, но она должна бать вычислена заранее и оформлена по всем правилам ФС
Правила для участка сканирования
- участок сканирования есть в любой ФС и определяется однозначно
- либо вся форматная строка 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 <== номера полей в строке
- вывод прекратится, так как данных больше нет