第二十一章 Caché 命令大全 READ 命令
接受输入并将其存储在变量中。
重点
-
READ
从当前I / O设备输入面向字符的数据。必须使用OPEN
命令打开设备,然后使用USE
命令将其建立为当前设备。 - 共有三种类型的
READ
操作:可变长度读取,固定长度读取和单字符读取. - 对于终端,通常通过按
键提供此终止符。 - 请注意,
read a#1
和read*a
都可以用于输入单个字符。但是,变量中存储的值不同:a#1
将输入字符存储在变量a
中;* a
将输入字符的ASCII数值存储在变量a
中;都将输入字符存储在$ ZB
特殊变量中。
大纲
READ:pc readargument,...
R:pc readargument,...
readargument可以是:
fchar
prompt
variable:timeout
*variable:timeout
variable#length:timeout
参数
- pc 可选-后置表达式
- fchar 可选-一个或多个格式控制字符。允许的字符为
!,#、?和/
。 - prompt 可选-字符串文字,为用户输入提供提示或消息。用引号引起来。
- variable 接收输入数据的变量。可以是局部变量,进程专用全局变量或全局变量。可以不下标或下标。
- length 可选-接受的字符数,指定为整数或计算结果为整数的表达式或变量。前面的#符号是必需的。
- timeout 可选-等待请求成功的秒数,指定为整数。小数秒将被截断为整数部分。前面的冒号(
:
)是必需的。如果省略,则Caché无限期等待。
可以通过用逗号分隔参数来指定一个以上的fchar或提示参数。
描述
READ
命令接受来自当前设备的输入。使用OPEN
和USE
命令建立当前设备。$ IO
特殊变量包含当前设备的设备ID。默认情况下,当前设备是用户终端。
READ
命令将暂停程序执行,直到它从当前设备接收输入或超时为止。因此,如果当前设备是用户终端,则不应在作为后台(非交互式)作业执行的程序中使用READ
命令。
variable
参数接收输入字符。如果未定义,则READ首先定义变量,如果它具有先前的值,则将其清除。因此,如果没有为变量输入任何数据(例如,如果在输入任何字符之前读取超时),则变量将定义并包含空字符串。如果输入的唯一字符是终止符
请注意,对于固定长度和可变长度读取,variable
不存储用于终止读取操作的终止符。单字符读取句柄变量的方式有所不同。对于单字符读取变量的使用,请参见下文。
如果指定了可选的超时值,则在输入所有字符之前,READ
可能会超时。如果读取超时,则在超时之前输入的那些字符将存储在变量中。在这种情况下,无需输入终止符;超时之前输入的字符将传输到变量,并且READ
终止,将$ TEST
设置为0。
共有三种类型的READ
操作:可变长度读取,固定长度读取和单字符读取。所有这些都可以使用或不使用超时参数来指定。单个READ
命令可以以这三种类型的任意组合包括多个READ
操作。每个读取操作均按从左到右的顺序独立执行。READ
命令还可以包含任意数量的逗号分隔的提示和fchar
参数。
三种类型的READ
操作如下:
- 可变长度读取具有以下格式:
READ variable
可变长度读取接受任意数量的输入字符,并将它们存储在指定的变量中。输入以终止符结束。对于终端,通常通过按
键提供此终止符。输入字符(而不是终止符)存储在变量中。
- 固定长度读取具有以下格式:
READ variable#length
固定长度的读取器接受最大长度的输入字符,并将它们存储在指定的变量中。当输入指定数量的字符或遇到终止符时,输入将自动结束。例如,在四个字符的固定长度读取中输入两个字符,然后按
键。输入字符(而不是终止符(如果有))存储在变量中。
- 单字符读取器具有以下格式:
READ *variable
单字符读取器接受单个输入字符,并将其等效的ASCII数值存储在指定变量中。它将字符本身存储在$ZB
和$KEY
特殊变量中。当输入单个字符时,输入自动结束。终止符字符被视为单字符输入,并按此方式存储。如果指定了可选的TIMEOUT参数,并且发生了超时,则TIMEOUT会将变量设置为-1。
参数
pc
可选的后置条件表达式。如果后置条件表达式为TRUE(计算结果为非零数值),则Caché执行该命令。如果后置条件表达式为假(计算结果为零),则Caché不执行该命令。
fchar
以下任何格式控制代码。当与来自键盘的用户输入一起使用时,这些控件确定指定的提示或用户输入区域将在屏幕上出现的位置。
-
!
开始新行。可以指定多个感叹号 -
#
开始新的一页。在终端上,它清除当前屏幕并从新屏幕的顶部开始。 -
?
第n列位置处的n个位置,其中n为正整数。 -
/Keyword
(参数)设备控件助记符。执行特定于设备的操作,例如将光标定位在视频终端上或倒回磁带。斜杠字符(/
)后面跟着一个关键字,该关键字后面还可以跟一个或多个用括号括起来的参数。多个参数用逗号分隔。关键字是当前设备的助记空间例程的入口点标签。
可以通过以下任一方式为设备类型建立默认助记空间:
- 进入管理门户,选择[主页]>[配置]>[设备设置]>[IO设置]。查看和编辑“文件”、“磁带”、“其他”或“终端助记空间”设置。
- 在设备的OPEN或USE命令中包含
/mmemonic
空格参数。
可以指定多个格式控件。例如:#!?20
表示从新页面(或屏幕)的顶部开始,向下三行,然后定位到列20。可以将格式控制字符与其他以逗号分隔的读取参数点缀在一起。例如:
DHC-APP> READ #!!,"Please enter",!,"your name: ",x,"THANK YOU
显示类似以下内容:
DHC-APP> READ #!!,"Please enter",!,"your name: ",x,"THANK YOU"
Please enter
your name: yxTHANK YOU
DHC-APP>
prompt
为用户使用终端键盘输入提供提示或消息的字符串文字。通常,提示符参数后跟一个变量,因此用户输入区域紧跟在显示的文字之后。可以使用一系列逗号分隔的提示和fchar
参数来指定多行提示或消息。
variable
要接收输入数据的局部变量、进程专用全局变量或全局变量。它可以是无下标的,也可以是下标的。如果指定的变量尚不存在,则Caché在读取操作开始时定义该变量。如果定义了指定的变量并具有值,则Caché会在读取操作开始时清除此值。
当输入字符时,它们在输入时存储在变量中。输入字符时,它们在输入时存储在变量中。a
如果指定了可选的超时参数,并且读取操作因超时而中断,则在此之前键入的字符将存储在变量中。(但是,请注意变量在遇到
中断时的行为,如下所述。)
非打印字符(如
)存储在变量中。终止符可用于结束任何类型的读取操作。例如,从终端按
键结束读取操作。对于可变长度或固定长度读取,此终止符不存储在变量中。终止符存储在变量中,用于单字符读取。
length
一个正整数,指定固定长度读取可接受的最大字符数。当输入指定数量的字符或遇到终止符时,读取完成。此参数是可选的,但如果指定,前面的#符号是必需的。
指定零或负数会导致
错误。但是,将忽略数字的前导零和小数部分,而使用整数部分。可以将LENGTH
指定为变量或解析为整数的表达式。
请注意,read a#1
和read*a
都可以用于输入单个字符。但是,变量中存储的值不同:a#1
将输入字符存储在变量a
中;* a
将输入字符的ASCII数值存储在变量a
中;都将输入字符存储在$ ZB
特殊变量中。这两种类型的单字符输入在如何处理终止符和如何处理超时方面也有所不同。
timeout
等待请求成功的秒数。此参数是可选的,但如果指定,则前面的冒号是必需的。必须将超时指定为整数或计算结果为整数的表达式。timeout参数将$ TEST
特殊变量设置如下:
- 带有超时参数的
READ
成功完成(不超时):$ TEST
设置为1(TRUE)。 - 带有超时参数的
READ
超时:$ TEST
设置为0(FALSE)。 -
READ
,无超时参数:$ TEST
保持设置为其先前值。
请注意,$ TEST
也可以由用户设置,也可以由LOCK
,OPEN
或JOB
超时设置。
如果超时时间在READ
完成之前到期并且已经输入了某些字符(对于可变长度或固定长度的读取),则将输入字符存储在变量中。如果未输入任何字符(用于可变长度或固定长度读取),则Caché定义变量(如有必要)并将其设置为空字符串。如果没有为单字符READ
输入任何字符,则Caché定义变量(如有必要)并将其设置为–1。
示例
下面的示例使用READ
的可变长度形式从用户那里获取任意数量的字符。格式控制!在新行上开始提示。
DHC-APP> READ !,"Enter your last name: ",lname
Enter your last name: yx
下面的示例使用READ
的单字符形式从用户那里获取一个字符并将其存储为ASCII数值。
/// d ##class(PHA.TEST.Command).TestRead()
ClassMethod TestRead()
{
READ !,"输入选项编号 (1,2,3,4): ",*opt
WRITE !,"ASCII value input=",opt
WRITE !,"Character input=",$KEY
}
DHC-APP>d ##class(PHA.TEST.Command).TestRead()
输入选项编号 (1,2,3,4): 1
ASCII value input=49
Character input=1
DHC-APP>d ##class(PHA.TEST.Command).TestRead()
输入选项编号 (1,2,3,4): a
ASCII value input=97
Character input=a
DHC-APP>w *97
a
下面的示例使用READ
的定长形式从用户那里获取三个字符。
DHC-APP>READ !,"Enter your 3-digit area code: ",area#3
Enter your 3-digit area code: 123
DHC-APP>READ !,"Enter your 3-digit area code: ",area#3
Enter your 3-digit area code: zyx
以下示例提示输入名称的三个部分:固定长度的给定名称(gname
)(最多12个字符),固定长度(一个字符)的中间名首字母(iname
)和任意一个家族名称(fname
)长度。gname和iname
变量被编码为在10秒后超时:
/// d ##class(PHA.TEST.Command).TestReadTest()
ClassMethod TestReadTest()
{
READ "Given name:",gname#12:10,!,
"Middle initial:",iname#1:10,!,
"Family name:",fname
WRITE $TEST
}
DHC-APP>d ##class(PHA.TEST.Command).TestReadTest()
Given name:123456789101
Middle initial:a
Family name:abcdefghigklm1
读取操作超时会使READ
命令继续进行下一个读取操作。前两个读取操作是否将$ TEST
设置为超时。第三次读取操作未设置$ TEST
,因此此示例中的$ TEST
的值反映了第二次读取操作的结果(成功或超时)。
以下示例使用间接来动态更改与READ
命令关联的提示:
/// d ##class(PHA.TEST.Command).TestReadIndirect()
ClassMethod TestReadIndirect()
{
PromptChoice
READ "键入1代表数字或2代表名字:",p,#!!!!
IF p'=1,p'=2 {
WRITE !,"输入无效" RETURN
}
ELSE {
DO DataInput(p)
}
DataInput(dtype)
SET MESS(1)="""输入一个数字:"""
SET MESS(2)="""输入名称:"""
SET x=1
READ !,@MESS(dtype),val(x)
IF val(x)="" {
WRITE !,"Goodbye" RETURN
}
ELSE {
IF dtype=1,1=$ISVALIDNUM(val(x)) {
WRITE !,"输入号码: ",val(x),!
} ELSEIF dtype=2 {
WRITE !,"输入字符串: ",val(x),!
} ELSE {
WRITE !,"不是数字",!
}
SET x=x+1
DO DataInput(dtype)
}
}
DHC-APP>d ##class(PHA.TEST.Command).TestReadIndirect()
键入1代表数字或2代表名字:1
输入一个数字:2
输入号码: 2
输入一个数字:3
输入号码: 3
输入一个数字:4
输入号码: 4
输入一个数字:5
输入号码: 5
输入一个数字:6
输入号码: 6
输入一个数字:7
输入号码: 7
输入一个数字:
Goodbye
DHC-APP>d ##class(PHA.TEST.Command).TestReadIndirect()
键入1代表数字或2代表名字:2
输入名称:a
输入字符串: a
输入名称:b
输入字符串: b
输入名称:c
输入字符串: c
输入名称:
Goodbye
以下示例根据输入的第一个数字的位数设置固定长度读取的长度:
/// d ##class(PHA.TEST.Command).TestReadLength()
ClassMethod TestReadLength()
{
FirstNum
READ "输入最大整数(然后按回车键): ",val(1)
SET ibuf=$LENGTH(val(1))
WRITE !,"最大的长度是: ",val(1),!
DO OtherNums(ibuf)
OtherNums(digits)
SET x=2
READ !,"输入下一个整数: ",val(x)#digits
IF val(x)="" {
WRITE !,"Goodbye" RETURN
} ELSEIF val(x)>val(1) {
WRITE !,"数字太大",!
DO OtherNums(digits)
} ELSE {
WRITE !,"输入: ",val(x),!
SET x=x+1
DO OtherNums(digits)
}
}
DHC-APP>d ##class(PHA.TEST.Command).TestReadLength()
输入最大整数(然后按回车键): 2
最大的长度是: 2
输入下一个整数: 3
数字太大
输入下一个整数:
Goodbye
DHC-APP>d ##class(PHA.TEST.Command).TestReadLength()
输入最大整数(然后按回车键): 9
最大的长度是: 9
输入下一个整数: 1
输入: 1
输入下一个整数: 2
输入: 2
输入下一个整数: 3
输入: 3
输入下一个整数: 5
输入: 5
输入下一个整数: 6
输入: 6
输入下一个整数:
Goodbye
DHC-APP>d ##class(PHA.TEST.Command).TestReadLength()
输入最大整数(然后按回车键): 3
最大的长度是: 3
输入下一个整数: 2
输入: 2
输入下一个整数: 2
输入: 2
输入下一个整数: 4
数字太大
输入下一个整数: 5
数字太大
输入下一个整数:
Goodbye
注意
READ
使用当前设备
READ
从当前I / O设备输入面向字符的数据。必须使用OPEN
命令打开设备,然后使用USE
命令将其建立为当前设备。Caché在$ IO
特殊变量中维护当前设备ID。
READ
的最常见用途是从键盘获取用户输入,但也可以使用它从任何面向字节的设备(例如磁带,顺序磁盘文件或通信缓冲区)中输入字符。
READ
取行回调
读取行用模式允许终端设备上的READ
命令接收先前输入的行作为其输入。然后可以编辑该调用的输入行。用户必须以与用户指定的输入相同的方式交互式地结束调用的行的输入。Caché支持可变长度终端读取(READ
变量)和固定长度终端读取(READ Variable#length
)的读取行调用。Caché不支持单字符终端读取(READ *
变量)的读取行调用。若要激活当前进程的读取行调用,请使用%SYSTEM.Process
类的LineRecall()
方法。若要将系统范围的读取行调用设置为默认值,请使用Config.Miscellaneous
类的LineRecall
属性。
READ
终止符
当输入字符串达到指定的长度(对于单字符READ
和固定长度READ
)时,Caché终止读取操作。对于可变长度的READ
,如果输入字符串达到当前进程的最大字符串长度,则Caché终止读取。
当Caché遇到某些终止符时,它也会终止读取。终止符由设备类型决定。例如,对于终端,默认终止符为RETURN
(也称为
键)(ASCII 13),LINE FEED(ASCII 10)和ESCAPE(ASCII 27)
。
对设备发出OPEN
或USE
命令时,可以修改终止符的默认值。OPEN
和USE
允许指定终止符参数值。
- 可变长度读取:Caché不会将输入终止符与输入值一起存储;它记录在
$ KEY
和$ ZB
特殊变量中。 - 固定长度的多字符
READ
:Caché不将输入终止符与输入值一起存储;它记录在$ KEY
和$ ZB
特殊变量中。 - 单字符读取:Caché将输入终止符(如果指定)存储为单字符读取的输入值。它还在
$ KEY
和$ ZB
特殊变量中记录输入终止符。
请注意,每次从终端读取命令行时,也会设置$ KEY
和$ ZB
特殊变量,从而覆盖由先前的READ命令设置的$ KEY
和$ ZB
值。
超时和$ ZA
,$ ZB
和$ TEST
特殊变量
Caché在$ TEST
,$ ZA
和$ ZB
特殊变量中记录READ
的完成状态,如下所示:
READ 类型 |
变量数据 | $TEST |
$ZA |
$ZB |
---|---|---|---|---|
变量,以行返回结尾 | 输入字符(如果没有则为空字符串) | 1 | 0 | 终止符 |
变量,输入,然后超时 | 输入字符 | 0 | 2 | null字符串 |
可变,无输入,超时 | 空字符串 | 0 | 2 | null字符串 |
固定,输入的所有字符 | 输入字符 | 1 | 0 | 输入的最后一个字符 |
固定,行返回 | 输入字符(如果没有则为空字符串) | 1 | 0 | 终止符 |
固定,超时 | 输入字符(或空字符串,如果没有) | 0 | 2 | null字符串 |
单字符,数据输入 | 输入字符的ASCII值 | 1 | 0 | 输入字符 |
单字符,终止符输入 | 终止符的ASCII值 | 1 | 0 |
终止符 |
单个字符,超时 | -1 | 0 | 2 | null字符串 |
$ZB
和 $KEY
$ ZB
和$ KEY
特殊变量对每种类型的读取返回完全相同的值,除了一种。当执行固定长度的读取并输入指定数量的字符时,读取将完成而没有终止符。在这种情况下,$ ZB
包含最后一个字符输入(终止符),而$ KEY
包含空字符串(不包含终止符)。
中断
如果在调用READ
时存在预期的CTRL-C
中断,则READ
会在从终端读取之前取消此中断。
如果正在进行的读取被CTRL-C
中断中断,则变量将恢复为先前的状态。例如,如果为读取操作输入了几个字符,然后发出CTRL-C
,则变量将返回到读取操作之前的状态。也就是说,如果未定义,它将保持未定义状态。如果它具有先前的值,则包含先前的值。此行为与超时的读取操作完全不同。读取超时将保留变量的新状态,包括发生超时之前输入的所有字符。如果READ
命令包含多个读取操作,则该中断仅影响正在进行的读取操作。要作为一个单元提交或还原多个读取操作,请使用事务处理。
从非键盘设备READ
如前所述,READ
可用于从任何面向字符的设备获取输入。这包括磁带和顺序磁盘文件之类的设备,以及终端键盘。但是,必须首先使用OPEN
和USE
命令建立要读取的设备作为当前设备。
对于非键盘设备,可以使用三种可用格式(可变长度,单字符和固定长度)中的任何一种。在任何给定情况下使用哪种形式的选择取决于可用终止符的类型。
例如,如果正在读取以行格式返回数据且以CARRIAGE RETURN / LINE FEED
作为行终止符的设备,则可以使用可变长度格式。在这种情况下,Caché会将每一行全部读入变量,仅当输入到达行尾的Return(ASCII码13
)时才终止输入。(请记住,从前面显示的用户输入示例中,是输入终止符。)
另一方面,如果正在从将记录显示为一系列固定长度字段的磁带上进行读取,则可以使用固定长度(variable#length
)形式。例如,假设有一个使用记录格式的磁带,该记录格式由四个字段组成,每个字段最多8个,12个,4个和6个字符。可能使用类似于以下代码的代码来读取数据:
READ field1#8,field2#12,field3#4,field4#6
在这种情况下,#n
值设置每个字段的输入终止符。
可以通过在OPEN
或USE
命令上为该设备指定的设备参数来设置给定设备使用的终止符。
从磁带读取面向块的数据时,$ ZB
特殊变量包含I / O缓冲区中剩余的字节数。它的功能与读取面向字符的数据时所使用的功能完全不同。在面向块的I / O期间,$ ZB
不包含读取的终止符或最后一个输入字符。
读取非印刷字符
非打印字符是超出ASCII
可打印字符标准范围的字符。换句话说,它们是ASCII
码小于ASCII 32
或大于ASCII 127
的字符。它们是标准键盘上没有等效单键的字符。
代码小于ASCII 32
的字符通常用于控制操作。只能与Ctrl键一起输入。例如,ETX(ASCII 3)
输入为
,并从键盘输入时用于断言BREAK
。
代码大于ASCII 127
的字符通常用于图形操作。通常,不能从键盘输入它们,但可以从其他类型的设备中读取它们。例如,ASCII 179
产生垂直线字符。
可以使用READ
命令输入非打印字符以及标准ASCII
可打印字符。但是,必须包含代码来处理用于每个此类字符的转义序列。转义序列是以Esc字符(ASCII 27
)开头的字符序列。例如,可以对READ
进行编码,以便允许用户按功能键作为有效的输入响应。按下功能键会产生一个转义序列,对于不同类型的终端,转义序列可能会有所不同。
ObjectScript支持将转义序列输入存储在$ ZB
和$ KEY
特殊变量中,而不是存储在指定变量中。例如,对于功能键按下,Caché将Esc代码(ASCII 27
)存储在$ ZB
和$ KEY
中。要处理转义序列,必须在每次READ
之后包含用于测试$ ZB
或$ KEY
中当前值的代码,因为后续的读取会更新这些特殊变量并覆盖以前的任何值。($ ZB
和$ KEY
非常相似,但不完全相同)要显示非打印字符,例如转义序列,请使用ZZDUMP
命令或$ ASCII
函数。
顺序文件结束
遇到顺序文件的文件结尾时,READ的行为取决于系统范围的默认值。转到管理门户,选择“系统”,“配置”,“兼容性设置”。查看和编辑SetZEOF
的当前设置。
当Caché在读取顺序文件时遇到意外的文件结尾时,此选项控制行为。设置为“ true”时,Caché设置$ ZEOF
特殊变量以指示您已到达文件末尾。设置为“ false”时,Caché发出错误。默认值为“ false”。
若要更改当前进程的文件结束行为,请使用%SYSTEM.Process
类的SetZEOF()
方法。要为文件结束行为设置系统范围的默认值,请使用Config.Miscellaneous
类的SetZEOF
属性。
默认记录长度
如果未指定要读取的字符数,则无论是否启用了长字符串,Caché都会假定默认长度为32,767个字符。