В PostScript есть несколько хитростей и ярлыков для File IO, которые часто не упоминаются во вступительных разделах книг PostScript.Самым секретом среди них является оператор «токен».Это позволяет заимствовать собственный сканер интерпретатора для чтения голого слова (создание объекта типа имени), числа (создание объекта типа integer или realtype) или их массива (но только если вы используете нотацию исполняемого массива, т.е.фигурные скобки, в противном случае вы просто получите объект marktype, который представляет левую квадратную скобку).
В качестве простого примера я часто использую этот однострочный элемент для встраивания расширенного раздела комментариев в программу postscript:
%!
{ currentfile token pop /END-COMMENT eq {exit} if } loop
Each word here is read from the current file and converted
into a name object and compared to "/END-COMMENT".
It can have but does not need a preceeding slash.
This program produces an image of a snowman in a blizzard,
suitable for use as stationary.
END-COMMENT
showpage
Редактировать: Теперь я понимаю, что это действительно ужасный ответ ... пока.
Мой пример выше немного больше, чем:
(Some
multi-line
text)
pop
Итак, на этот раз по-настоящему.
Для начала вам понадобится loop
.
{
} loop
Внутри этого цикла вы читаете некоторые данные.
/src (datafile) (r) file def
{
src readline
} loop
Как вы заметили, все операторы чтения файлов возвращают логическое значение в верхней части стека.Отлично!
/src (datafile) (r) file def
{
src readline {
}{
exit
} ifelse
} loop
Таким образом, логическое true будет что-то делать и продолжать цикл, но логическое false (no-more-data) приводит к завершению цикла.Но для readline
нужна строка, в которую нужно поместить свои данные.И он возвращает строку даже в ложном случае.
/src (datafile) (r) file def
/str 80 string def
{
src str readline {
processline
}{
pop exit
} ifelse
} loop
Теперь у нас есть строка, содержащая строку (максимум 80 символов) данных из файла.Если он вообще напоминает синтаксис Postscript, вы можете использовать token
в цикле (как в моем первом примере; он читает каждое слово из файла, преобразует его в имя исполняемого файла, а затем сравнивает его с буквальным именем; если имена совпадают;, выйти из цикла).Или вы можете использовать get
в цикле (или цикле forall
), чтобы извлечь каждый байт как целое число.Но самое интересное, что нужно сделать, это search
.
Эта процедура сканирует строку на наличие слов, разделенных пробелами, и выводит каждое из них на стандартный вывод в отдельной строке.
/processline { % (line)
( ) { % (line) ( )
search { % (post) ( ) (pre)
=
}{ % (no-match)
=
exit
} ifelse
} loop
} def
Обычно это прощепросто для того, чтобы дублировать случаи здесь, когда вы хотите сделать то же самое с последним словом, как и все остальные.Вы можете сделать некоторые хитрые вещи для обработки самой верхней строки и затем протестировать логическое значение;но это действительно не стоит хлопот.Крутая вещь в search
- это удобный порядок, в котором он возвращает свои результаты.Он помещает начало строки сверху, чтобы вы могли работать с ним.Затем он дает вам «match» (который совпадает с «поиском», который вы дали изначально (хотя теперь он ссылается на рабочую строку)) и остаток;и они уже в правильном порядке для следующего обхода цикла.
Так что вы хотите сделать с вашими извлеченными, разделенными пробелом словами, прочитанными из внешнего файла?
Если они представляют числа, вы можете cvi
или cvr
их и делать арифметику.Если они буквенно-цифровые, вы можете print
или show
их;или cvn
их и используйте их как атомарные символы.