The X format item sets a stream file or character-string expression to a column relative to the current position. It is the only control format item that can be used with either the FILE or STRING option of GET EDIT and PUT EDIT. The form of the X format item is:
wAn integer, or an expression, that specifies a number of consecutive character positions in the stream; w must not yield a negative integer value. If w yields zero, no operation is performed. If the w is omitted, its value is assumed to be 1.
Input with GET EDIT
On input, the next w columns after the current column are skipped.
Output with PUT EDIT
On output, w spaces are inserted following the current column.
When the output stream is a file, and the end of the current line is reached, the output of spaces continues on the next line until w spaces have been output. The size of the current line is either the default value or the specific value you have established for the file (see Section 9.1 for LINESIZE option). If the file is a print file, the ENDPAGE condition is signaled if the page size is reached; on normal return from the ENDPAGE ON-unit, output of spaces continues at the top of the next page until w spaces have been output.
If the output stream is a character-string variable, w spaces are written to the variable. The ERROR condition is signaled if the maximum length of the string is exceeded.
XFOR: PROCEDURE OPTIONS(MAIN); DECLARE INLINE CHARACTER(80) VARYING; DECLARE FIRSTWORD CHARACTER(80) VARYING; DECLARE OUTFILE PRINT FILE; DECLARE SPACE1 FIXED; GET EDIT(INLINE) (A(1000)) OPTIONS(PROMPT('Line>')); SPACE1 = INDEX(INLINE,' '); /* position of first wordbreak */ FIRSTWORD = SUBSTR(INLINE,1,SPACE1-1); PUT STRING(FIRSTWORD) EDIT (FIRSTWORD,'-FIRST WORD TYPED') (A,X(2),A); PUT SKIP FILE(OUTFILE) LIST(FIRSTWORD); END XFOR;
The GET EDIT statement in the program XFOR inputs a complete line from a user's terminal, after issuing and receiving an answer to the prompt <BIT_STRING>(Line>). Assume that the interaction is as follows:
Line> beautiful losers[Return]
beautiful -FIRST WORD TYPED
The X format item has correctly inserted two spaces between <BIT_STRING>(beautiful) and <BIT_STRING>(-FIRST WORD TYPED).
XFOR2: PROCEDURE OPTIONS(MAIN); DECLARE INLINE CHARACTER(80) VARYING; DECLARE OUTFILE2 PRINT FILE; GET EDIT(INLINE) (X(10),A(1000)) OPTIONS(PROMPT('Line>')); PUT SKIP FILE(OUTFILE2) LIST(INLINE); END XFOR2;
In the program XFOR2, the GET EDIT statement skips the first 10 characters typed after the prompt and then inputs the remainder of the line. Assume that the interaction is:
The first 10 letters (A to J) have been ignored on input.
22.214.171.124 Format Specifications
In the GET EDIT, PUT EDIT, and FORMAT statements, format items are used singly or in combination to create format specifications. The syntax of a format specification is as follows:
The iteration factor is an integer or an integer expression that repeats the following format item or the following list of format specifications. Expressions must be enclosed in parentheses. If an integer iteration factor precedes a single format item that is not in parentheses, the iteration factor and the format item must be separated by a space. For example:
PUT EDIT (A) (F(5,2));
PUT EDIT (A,B) (2F(5,2));
PUT EDIT (A,B) (2 (F(5,2)));
An iteration factor can also repeat an entire list of format specifications:
PUT EDIT ( (A(I) DO I = 1 TO 10) ) /* 10 array elements */ ( 2( F(5,2),2(F(7,2),E(8)) ) ); /* 10 format items */
Expanded into individual format items, this specification looks like this:
If an expression is used as the iteration factor, it must be enclosed in parentheses, but does not require spaces. For example:
PUT EDIT (A) ((Z*4)F(5,2));
In general, data listed in the GET EDIT or PUT EDIT statement is matched to the expanded list of data format items, from left to right, until the end of the input-target or output-source list is reached. Matching occurs only between I/O data and data format items; control format items are executed only if they are encountered while the matching is in progress.
Format-specification lists are used in GET EDIT, PUT EDIT, and FORMAT statements to control the conversion of data between the program and the input or output stream and to precisely control positioning within the input or output stream. This entry describes the syntax of format-specification lists and the manner in which a format list is processed to acquire or transmit data.
Rules for Use
This section briefly describes rules and constraints for format-specification lists.
How Edit-Directed Operations Are Performed
This section describes the manner in which format items are matched to input targets or output sources.
All edit-directed input statements include the following syntax:
EDIT (input-target,...) (format-specification,...)
All edit-directed output statements include the following syntax:
EDIT (output-source,...) (format-specification,...)
format-specificationOne of the following:
- A single control or data format item.
- A construct containing an iteration factor followed by one or more format items.
- An R format item, which specifies the label of a FORMAT statement. In effect, the entire format-specification list in the FORMAT statement is acquired and inserted at the position of the R format item.
Except for picture (P) and remote (R) format items, arguments to format items can be integer expressions.
input-targetOne of the following:
- A variable reference, which can be to a scalar or aggregate variable of any computational data type
- A construct with the following syntax:
(input-target,... DO reference=expression[TO expression]
[BY expression] [WHILE(expression)][UNTIL(expression)] )
- A construct with the following syntax:
(input-target,... DO reference=expression[REPEAT
expression] [WHILE (expression)][UNTIL(expression)] )
output-sourceOne of the following:
- Any expression with a computational value, including references to scalar or aggregate variables of any computational type
- A construct containing a DO specification, as shown for input targets
When PL/I performs an edit-directed operation, it examines the list of input targets or output sources, beginning with the first in the list. If the target or source is an array or structure or contains a DO specification, it is expanded to form a list of individual data items; an array is expanded in row-major order, a structure is expanded in the order of its declaration, and items preceding a DO specification are expanded according to the DO specification.
Within a single target or source, items at the innermost level of parentheses are processed first.
Given a list of one or more data items contained in the first target or source, PL/I processes the data items from left to right. Beginning with the leftmost data item, and for each subsequent item, PL/I executes format items until the data item has been either assigned a value from the input stream, or converted to a character representation and placed in the output stream. Control format items are therefore executed in the order in which they occur in the format-specification list. With the first target or source, the execution of format items begins with the leftmost format item in the format-specification list. If the end of the format-specification list is reached, PL/I returns to the leftmost format item and continues.
When all items contained in the first target or source have been processed, PL/I operates on the next target or source. The target or source is evaluated, and PL/I then examines the format-specification list, beginning where the previous operation stopped.
This processing continues until all data items in the input-target or output-source list have been processed, at which point the edit-directed statement terminates. If this occurs while PL/I is in the middle of the list of format items, the format items to the right are not executed.
The following examples show typical edit-directed operations. All cases shown are for input (GET EDIT), but the operations for PUT EDIT are similar. The simple cases, shown first, are with input targets that are scalar variable references. The next cases shown are with aggregate (array and structure) references. The last cases shown are with DO specifications.
Scalar VariablesThe following examples have input targets that are scalar variables:
GET EDIT (A,B,C,D) (A(12),F(5,2),F(6,2),A(14));
This statement acquires four values from the input stream: a 12-character string, a 5-digit fixed-point decimal number, a 6-digit fixed-point decimal number, and a 14-character string, and assigns these values, with any necessary conversions, to the target variables A, B, C, and D, respectively.
GET EDIT (A,B,C,D) (A(12));
This statement acquires four 12-character strings and assigns them (with conversions, if necessary) to the targets A, B, C, and D.
GET EDIT (A,B,C,D) (A(12), 2 F(5,2), A(14));
This statement acquires a 12-character string, two fixed-point decimal numbers, and a 14-character string, in that order, and assigns them to A, B, C, and D. (You can use embedded spaces in format lists, as elsewhere, for clarity; the space between 2 and F(5,2) is required.)
GET EDIT (A,B,C,D,E) ( 2( A(12),A(14) ), A(20) );
This statement acquires, in order, a 12-character string, a 14-character string, another 12-character string, another 14-character string, and a 20-character string, and assigns the strings, in that order, to A, B, C, D, and E.
GET EDIT (A,B,C,D,E) ( 2( A(12),A(14) ), SKIP, A(20) );
This statement performs the same operation as in the previous example, but acquires the 20-character string from the next line.
AggregatesThe following examples have input targets that are references to array and structure variables:
A is an array of five elements or a structure with five scalar members. This statement expands A to a list of individual data items. Then it acquires, in order, a 12-character string, a 14-character string, another 12-character string, another 14-character string, and a 20-character string, and assigns the strings, in that order, to the elements A(1) through A(5) (if an array) or to the five members of structure A in the order in which the members are declared.
GET EDIT (A) ( 2( A(12),A(14) ), A(20) );
Both A and B are aggregates with five elements or members. For A, this statement performs the same operation as in the previous example, and then repeats the operation for B, using the same format list each time. Because there are five format items specified, and the aggregates both have five elements or members, strings of the same length are acquired for corresponding elements of A and B.
GET EDIT (A,B) ( 2( A(12),A(14) ), A(20) );
NAME is a structure declared as:
GET EDIT (NAME) (SKIP,A(20),SKIP,A(80));
DECLARE 1 NAME 2 FIRST CHARACTER(20) VARYING, 2 LAST CHARACTER(80) VARYING;
This statement skips to the next line and acquires a 20-character string. It assigns the string to NAME.FIRST. This statement skips to the next line and acquires an 80-character string. This statement assigns that string to NAME.LAST.
Both A and B are 4-element arrays. From the current line, this statement executes A(12), A(14), A(12), and A(14), in that order, and assigns the results to A(1) through A(4). This statement then skips to the next line and executes A(20), A(12), A(14), and A(12), in that order, and assigns the results to B(1) through B(4); the list of data items is now exhausted, so this statement does not execute SKIP a second time.
GET EDIT (A,B) ( 2( A(12),A(14) ), SKIP, A(20) );
DO SpecificationsThe following examples have input targets that include DO specifications. The DO specifications control the assignment of input values to variables that are arrays and based structures.
B is a 10-element array. Notice that the parentheses surrounding the first input target are in addition to the parentheses surrounding the entire input-target list. This statement executes the format items A(12), A(14), A(12), and A(14), in that order, and assigns the resulting strings to elements B(10), B(8), B(6), and B(4), respectively. This statement then executes A(20) and assigns the result to B(1).
GET EDIT ( (B(I) DO I=10 TO 4 BY -2) , B(1) ) ( 2( A(12),A(14) ), A(20) );
A is a two-dimensional array of 20 rows and 10 columns. Two hundred decimal integers are acquired and assigned to the array elements in the order A(1,1), A(1,2),... ,A(20,10). Elements with odd-numbered columns receive 5-digit integers, and those with even-numbered columns, 6-digit integers. Because the DO specifications specify row-major order, the same operation is performed by the next example.
GET EDIT ( ( (A(I,J) DO J=1 TO 10) DO I=1 TO 20) ) (F(5),F(6));
GET EDIT (A) (F(5),F(6));
Because row-major order is the default, nested DO specifications are used to change the order in which values are assigned.
The example has the same effect as the following DO-group:
DO I = 1 TO 20; DO J = 1 TO 10; GET EDIT(A(I,J)) (F(5),F(6)); END; END;
Compared with a DO construct in the input-target list, however, the use of nested DO groups is much less efficient in execution speed. In addition, the identical effect is not generally true for all stream I/O statements. For instance:
GET SKIP EDIT(input-target,...) (format-specification,...);
This statement has different effects in the two cases. If it occurs in a pair of nested DO groups, as shown previously, the SKIP option is executed on each iteration of the innermost DO group. If instead the DO specifications are in the input-target list, the SKIP option is executed only once, before any other input processing is performed.
CURRENT and FIRST are pointers, and PERSON is a based structure declared as:
GET EDIT ( ( CURRENT->PERSON.NAME DO CURRENT = FIRST REPEAT CURRENT->PERSON.NEXT WHILE (CURRENT ^= NULL) ) ) (A(80));
DECLARE /* Based structure for list elements: */ 1 PERSON BASED, 2 NEXT POINTER, /* Pointer to next element: */ 2 NAME CHARACTER(80) VARYING; DECLARE /* NULL function and pointers to first and current list elements: */ NULL BUILTIN, (FIRST,CURRENT) POINTER;
The GET EDIT statement acquires 80-character strings from the input stream and assigns each to a list member PERSON.NAME. On the first input operation, the string is assigned to FIRST->PERSON.NAME. On subsequent iterations of the DO specification, the pointer to the next element, PERSON.NEXT, is assigned to CURRENT before the input operation. Before each input operation, including the first, the WHILE clause tests to determine whether the end of the queued list has been reached (indicated by the null pointer).
The DO REPEAT construct is often used in this type of application. You should provide a WHILE or UNTIL clause in this or any DO REPEAT construct to be sure that the operation has a defined termination. However, the WHILE or UNTIL clause is not required.
If the input or output stream is a character string, the processing is similar to the processing of files, but the positioning options are more limited:
In most applications, the terminal is treated as a stream file. You can explicitly declare a stream file to be associated with a user's terminal. The stream input and output statements, GET and PUT, use the default PL/I files SYSIN (the terminal) and SYSPRINT, respectively, when no file reference is included in the statement.
This file is associated with the default system input file SYS$INPUT,
which in turn is usually assigned to the user's terminal. The PL/I
print file SYSPRINT is associated with the default system file
SYS$OUTPUT, which, in interactive mode, is also assigned to the user's
terminal. For further information, see the Kednos PL/I for OpenVMS Systems User Manual.
126.96.36.199 Simple Input from a Terminal
Simple input from a terminal is accomplished with the GET LIST statement, which in its simple form has the following format:
GET LIST (input-target,...);
Because this statement has no reference to a specific file, the default file SYSIN (the terminal) is assumed. When this GET LIST statement is executed in a program, the program pauses until enough values are typed by the user to satisfy the input-target list.
The user must separate the values with the Return key, spaces, or commas. The user must press the Return key to send the typed line to the program.
In the context of simple terminal input, the input targets are usually simple variable references. For example:
GET LIST (SALARY,CONTRIBUTION(42),PAYROLL.DEDUCTION);
15500,500,1200[Return] 15500[Return]500[Return]1200[Return] 15500 500[Return]1200[Return]
If you press Return in response to an input request from GET LIST, the null character string '' is assigned to the input target. If you press Return in response to an input request from GET EDIT, the requested field width is filled with spaces and assigned to the input target under control of the corresponding format item. (Note that an all-space field causes an error for B formats.)
For full details on input targets, see the GET LIST statement ( Section 9.2.2).