在 postscript 中的 File IO 有一些技巧和快捷方式,这些技巧和快捷方式通常不会在 postscript 书籍的介绍部分中提及。其中最保守的秘密是“令牌”运算符。它允许您借用解释器自己的扫描仪来读取裸词(生成名称类型对象)、数字(生成
integertype 或 realtype 对象)或这些数组(但前提是您使用可执行数组表示法,即花括号,否则您只会得到一个表示左方括号的 marktype 对象)。
作为一个简单的例子,我经常使用这个单行代码在后记程序中嵌入一个扩展的评论部分:
%!
{ 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。
此过程扫描字符串以查找以空格分隔的单词并将每个单词打印到 stdout 的单独行。
/processline { % (line)
( ) { % (line) ( )
search { % (post) ( ) (pre)
=
}{ % (no-match)
=
exit
} ifelse
} loop
} def
当您想对最后一个单词做同样的事情时,在这里复制案例通常更容易。你可以做一些棘手的事情来处理最上面的字符串,然后然后测试布尔值;但这并不值得麻烦。 search 最酷的地方在于它返回结果的便捷顺序。它将字符串的开头放在顶部,以便您可以使用它。然后它为您提供“匹配”(与您最初提供的“搜索”相同(尽管现在它引用了工作字符串))和其余部分;并且它们已经按照正确的顺序进行下一次循环。
那么,您想如何处理从外部文件中读取的提取的、以空格分隔的单词?
如果它们代表数字,您可以cvi 或cvr 对它们进行算术运算。如果它们是字母数字,您可以print 或show 他们;或cvn 它们并将它们用作原子符号。