DocumentationEndless PL/I for POSIX SystemsReference Manual  ·  ESS-PFURM-001

Chapter 9

Input and Output

PL/I provides two distinct types of I/O processing, each of which handles input and output data in a different manner, and each of which has a unique set of I/O statements. These types of I/O are:

  • Stream (the GET and PUT statements)

  • Record (the READ, WRITE, DELETE, and REWRITE statements)

When a file is read or written with stream I/O, the data is treated as if it formed a continuous stream. Individual fields of data within the stream are delimited by commas, spaces, and record boundaries. A stream I/O statement specifies one or more fields to be processed in a single operation.

When a file is read or written with record I/O, however, a single record is processed upon the execution of an I/O statement.

This chapter describes I/O concepts that apply to both stream and record I/O.

9.1. Opening and Closing Files

This section discusses the following:

  • File declarations

  • File variables

  • Opening a file

  • File description attributes and options

  • File access modes

  • Closing a file

9.1.1. File Declarations

A file declaration specifies an identifier, the FILE attribute, and one or more file description attributes that describe the type of I/O operation that will be used to process the file.

A file is denoted in an I/O statement by the FILE option as follows:

FILE(file-reference)
file-reference

The name specified in the file declaration. For example:

DECLARE INFILE FILE SEQUENTIAL INPUT;
OPEN FILE(INFILE);

Here, INFILE is the name of a file constant. A file constant is an identifier declared with the FILE attribute and without the VARIABLE attribute. Except for the default file constants SYSIN and SYSPRINT, all files must be declared before they can be opened and used.

By default, all file constants have the EXTERNAL attribute. Any external procedure that declares the identifier with the FILE attribute and without the INTERNAL attribute can access the same file constant and, therefore, the same physical file.

9.1.2. File Variables

In PL/I, you can also refer to files using file variables and file-valued functions. For example:

DECLARE ANYFILE FILE VARIABLE;
⋮
ANYFILE = INFILE;
OPEN FILE(ANYFILE);

If INFILE is declared as in the previous example, the OPEN statement opens the file INFILE.

A file variable can also be given a value by receiving a file constant or variable passed as an argument, or by receiving a file constant or variable as the value of a function. For example:

GETFILE: PROCEDURE (PRINTFILE);
DECLARE PRINTFILE FILE VARIABLE;

This file variable is given a value when the procedure GETFILE is invoked.

9.1.3. Opening a File

A file is opened explicitly by an OPEN statement or implicitly by a READ, WRITE, REWRITE, DELETE, PUT, or GET statement issued for a file that is not open.

The OPEN statement explicitly opens one or more PL/I files with a specified set of attributes that describe the file and the method for accessing it. The format of the OPEN statement is as follows:

OPEN FILE(file-reference) [file-attributes-and-options ...]
       [,(file-reference) [file-attributes-and-options ...]] ...;
FILE(file-reference)

A reference to the file to be opened. If the file is already open, the OPEN statement has no effect. Therefore, if you want to change any attributes of an open file, you should first close it, and then reopen it with the new attributes.

file-attributes-and-options

The attributes and options of the file. The attributes specified are merged with the permanent attributes of the file specified in its declaration, if any. Then, default rules are applied to the union of these sets of attributes to complete the set of attributes in effect while the file is open.

The attributes you can specify with the OPEN statement are as follows:

BUFFERED (ibm dialect only)PRINT
DIRECTRECORD
ENVIRONMENT(option,...) (dec and ansi dialects only)SEQUENTIAL
INPUTSTREAM
KEYEDUNBUFFERED (ibm dialect only)
OUTPUTUPDATE

The file attributes are described in Chapter 2, Declarations .

The OPEN options are described in Section 9.1.3.1, “OPEN Statement Options”.

Examples
DECLARE                        INFILE FILE,
       STATE_FILE FILE KEYED;

OPEN                   FILE (INFILE),
       FILE (STATE_FILE) UPDATE;
       ⋮
CLOSE FILE (STATE_FILE);
OPEN FILE (STATE_FILE) INPUT SEQUENTIAL;

The DECLARE and OPEN statements for INFILE do not specify any file description attributes; PL/I applies the default attributes STREAM and INPUT. If any statement other than GET is used to process this file, the ERROR condition is signaled.

The file STATE_FILE is declared with the KEYED attribute. With the first OPEN statement that specifies this file, it is given the UPDATE attribute and opened for updating; that is, READ, WRITE, REWRITE, and DELETE statements can be used to operate on records in the file. The KEYED attribute implies the SEQUENTIAL attribute; thus, records in the file can be accessed sequentially or by key.

The second OPEN statement specifies the INPUT and SEQUENTIAL attributes. During this opening, the file can be accessed by sequential and keyed READ statements, but REWRITE, DELETE, and WRITE statements cannot be used.

DECLARE COPYFILE FILE OUTPUT;
OPEN FILE(COPYFILE) TITLE('COPYFILE.DAT');

The file specified by the file constant COPYFILE is opened for output. Each time this program is run, it creates a new version of the file COPYFILE.DAT.

9.1.3.1. OPEN Statement Options

The options that you can use in the OPEN statement are:

LINESIZE Option

The LINESIZE option specifies the maximum number of characters that can be output on a single line when the PUT statement writes data to a file with the STREAM and OUTPUT attributes. The format of the LINESIZE option is:

LINESIZE(expression)
expression

A fixed-point binary expression in the range 1 to 32767, giving the number of characters per line. If the expression is outside this range, a run-time error occurs.

The value specified in the LINESIZE option is used as the output line length for all subsequent output operations on the stream file, and it overrides the system default line size.

In the ibm dialect, if RECSIZE was specified in the declaration of a stream file, it is used as the output line length. However, if LINESIZE is specified in the OPEN statement, it overrides the previous RECSIZE specification.

The default line size is as follows:

  • If the output is to a physical record-oriented device, such as a line printer or terminal, the default line size is determined by the device.

  • If the output is to the default file, SYSPRINT, the default line size is 80.

  • If the output is to a print file, the default line size is 132.

  • If the output is to a nonrecord device (magnetic tape), the default line size is 510.

The line size is used by output operations to determine whether output will be placed on the current line or on the next line.

PAGESIZE Option

The PAGESIZE option is used in the OPEN statement to specify the maximum number of lines that can be written to a print file without signaling the ENDPAGE condition. The format of the PAGESIZE option is:

PAGESIZE(expression)
expression

A fixed-point binary expression in the range 1 through 32767, giving the number of lines per page. If the expression is outside this range, a run-time error occurs.

The value specified in the PAGESIZE option is used as the output page length for all subsequent output operations on the print file, and overrides the system default page size. The default page size is the following:

  • If the environment variable SYS$LP_LINES is defined, the default page size is the numeric value of SYS$LP_LINES minus 6.

  • If SYS$LP_LINES is not defined, or if its value is less than 30 or greater than 99, or if its value is not numeric, the default page size is 60.

During output operations, the ENDPAGE condition is signaled the first time that the specified page size is exceeded.

The PAGESIZE option is valid only for print files.

TITLE Option

The TITLE option is specified in an OPEN statement to designate the external file specification of the file to be associated with the PL/I file. The TITLE option is specified only on the OPEN statement for a file. Its format is as follows:

TITLE(expression)
expression

A character-string expression which represents an external file specification for the file.

For details on how the file specification is determined see the Section 9.1.3.4, “Determining the File Specification”.

9.1.3.2. Effects of Opening a File

Opening a file in PL/I has the following effects:

  • Any permanent attributes specified in a DECLARE statement of a file constant are merged with the attributes specified in the OPEN statement, if any, or with the attributes implied by the context of the opening. (For example, if no attributes are specified for a file in its declaration, and the first reference to the file is a GET statement, PL/I opens the file with the INPUT and STREAM attributes.) The rules that PL/I follows in applying default attributes are described in the next section.

  • The merged attributes apply to the file for the duration of this opening only. When the file is closed, only its permanent attributes remain in effect.

  • The file specification of the file is determined. This process is described in Section 9.1.3.4, “Determining the File Specification”.

  • If the file already exists, it is located and its attributes are checked for compatibility with the attributes specified or implied by the OPEN statement.

  • If the file does not exist, and if the attempted access does not require that the file exist, PL/I creates a new file using the attributes specified or implied to determine the file's organization.

  • If the file is opened successfully, the file is positioned.

Each of these steps is described in more detail below. If an error occurs during the opening of a file, the UNDEFINEDFILE condition is signaled (see the Endless PL/I for POSIX Systems User's Manual for more information on handling conditions).

9.1.3.3. Establishing the File's Attributes

The description attributes specified when a file is opened are merged with the file's permanent attributes. Duplicate specification of an attribute is allowed only for an attribute that does not specify a value.

An incomplete set of attributes is augmented with implied attributes. Table 9.1, “File Description Attributes Implied when a File is Opened” summarizes the attributes that can be added to an incomplete set.

Table 9.1. File Description Attributes Implied when a File is Opened
AttributeImplied Attributes
DIRECTRECORD KEYED
KEYEDRECORD
PRINTSTREAM OUTPUT
SEQUENTIALRECORD
UPDATERECORD

If the set of attributes is still not complete, PL/I uses the following steps to complete the set:

  1. If neither STREAM nor RECORD is present or implied, STREAM is supplied.

  2. If neither INPUT, nor OUTPUT, nor UPDATE is present, INPUT is supplied.

  3. If RECORD is specified, but neither SEQUENTIAL nor DIRECT is present or implied, SEQUENTIAL is supplied.

  4. If the file is associated with the external file constant SYSPRINT, and the attributes STREAM and OUTPUT are present but the attribute PRINT is not, PRINT is supplied.

  5. If the set contains the LINESIZE option, it must contain STREAM and OUTPUT. If it contains these attributes and does not contain LINESIZE, the default system line size value is supplied.

  6. If the set contains the PAGESIZE option, it must contain PRINT. If PRINT is present but PAGESIZE is not, the default system page size is supplied.

The completed set of attributes applies only for the current opening of the file. The OPEN command does not change the permanent file attributes, specified in the file declaration.

9.1.3.4. Determining the File Specification

PL/I uses the value of the TITLE option to determine the file specification, that is, the actual name of the file or device on which the I/O is to be performed. The determination of the file specification depends on the following system-specific functions:

  1. The value of the TITLE option can be an environment variable, or a portion of it can contain an environment variable. In either case, the environment variable is translated. If the resulting name is an environment variable, that name is also translated, to a maximum of 10 translations.

  2. After translation, PL/I applies any default values specified in the DEFAULT_FILE_NAME option of the ENVIRONMENT attribute list.

  3. If the file specification is still not complete, system defaults are applied to the incomplete portions of the file specification.

If a file name is not specified, PL/I uses the default name, which is the name of the file constant which declared the file.

The maximum length of the expanded file specification is 128.

The rules for environment variable translation and for the application of system defaults are described in the Endless PL/I for POSIX Systems User's Manual.

9.1.3.5. Accessing an Existing File

A file opening accesses an existing file if the file specified by the TITLE option actually exists and if the following attributes are present:

  • The file is opened for INPUT or UPDATE.

  • The file is opened with the OUTPUT attribute and with the ENVIRONMENT(APPEND) option.

Whenever PL/I accesses an existing file, the file's organization is checked for compatibility with the PL/I attributes specified. If any incompatibilities exist, the UNDEFINEDFILE condition is signaled.

9.1.3.6. Creating a File

A file opening creates a new file if the following are all true:

  • The OUTPUT attribute is specified.

  • The TITLE option, after name translation and the application of system defaults, specifies a mass-storage device (such as a disk or a tape).

  • The ENVIRONMENT(APPEND) option is not specified.

You can specify the organization and record format of a new file with ENVIRONMENT options. If no ENVIRONMENT options are given, the new file's organization is determined as follows:

  • If the KEYED attribute is present, PL/I creates a relative file with a maximum record size of 480 bytes and a maximum record number of -2147883647.

  • If the PRINT attribute is present, PL/I creates a sequential file with variable-length records, maximum record length of 508, and a 2 byte fixed-control field used to store carriage-control information.

  • If neither KEYED nor PRINT is specified, PL/I creates a sequential file with variable-length records and a maximum record size of 510 bytes.

When a file is opened with the RECORD and OUTPUT attributes, only WRITE statements can be used to access the file. If the file has the KEYED attribute as well, the WRITE statements must include the KEYFROM option.

9.1.3.7. File Positioning

When PL/I opens a file, the initial positioning of the file depends on the type of file (record or stream), the access mode, and certain ENVIRONMENT options.

For a definition of the file-positioning information for record files, see Section 9.3.6, “Position Information for a Record File”. For a definition of file-positioning information for stream files, see Section 9.2.1, “Processing and Positioning of Stream Files”.

9.1.4. File Description Attributes and Options

The file description attributes are summarized in Table 9.2, “Summary of File Description Attributes”. These attributes can be specified on DECLARE and OPEN statements.

Table 9.2. Summary of File Description Attributes
AttributeDescription
BUFFEREDRecords must pass through intermediate storage buffers. (ibm dialect only)
DIRECTRecords in the file will be accessed randomly.
INPUTThe file is an input file and will only be read.
KEYEDRecords in the file will be accessed by key.
OUTPUTThe file is an output file and will only be written.
PRINTThe file will be output on a printer or terminal.
RECORDThe file will be accessed with record I/O statements.
SEQUENTIALRecords in the file will be accessed sequentially.
STREAMThe file will be accessed with stream I/O statements.
UNBUFFEREDRecords need not pass through intermediate storage buffers.(ibm dialect only)
UPDATEThe file will be accessed for both reading and writing, and records can be rewritten and deleted.

For detailed descriptions of these attributes, see Chapter 2, Declarations .

9.1.5. Closing a File

The CLOSE statement dissociates PL/I files from the physical files with which they were associated when opened. The format of the CLOSE statement is as follows:

CLOSE FILE (file-reference) [ENVIRONMENT(DELETE)]
       [,FILE(file-reference) [ENVIRONMENT(DELETE)]] ...;
FILE(file-reference)

A file to be closed. If the file is already closed, the CLOSE statement has no effect.

ENVIRONMENT(DELETE)

The DELETE ENVIRONMENT option is valid for the CLOSE statement in the dec and ansi dialects of Endless PL/I for POSIX Systems. The DELETE environment option specifies that the file is to be deleted when it is closed. For more information see the Endless PL/I for POSIX Systems User's Manual.

Examples

This CLOSE statement closes the file constant INFILE:

CLOSE FILE(INFILE);

Another example of a CLOSE statement is:

DECLARE STATE_FILE FILE KEYED;

OPEN FILE(STATE_FILE) DIRECT UPDATE;
       ⋮
CLOSE FILE(STATE_FILE);
OPEN FILE(STATE_FILE) INPUT SEQUENTIAL;

The file STATE_FILE is declared with the KEYED attribute. The first OPEN statement that specifies this file is given the DIRECT and UPDATE attributes and opened for updating; the file can be accessed only by key.

The CLOSE statement closes the file. The second OPEN statement specifies the INPUT and SEQUENTIAL attributes; the file can now be accessed sequentially.

9.2. Stream I/O

Stream I/O is one of the two general kinds of I/O performed by PL/I. Stream input and output is performed by the statements GET and PUT, respectively. Both statements can perform either list- directed or edit-directed operations.

In stream I/O, more than one record or line can be processed by a single statement, and, conversely, multiple statements can process a single line or record. In contrast, record I/O only processes one record of a file in each READ or WRITE statement.

Table 9.3, “Attributes and Access Modes for Stream Files” summarizes the file description attributes and access modes for stream files.

Table 9.3. Attributes and Access Modes for Stream Files
Attributes SpecifiedAttributes ImpliedValid Devices and File OrganizationsUsage
PRINTSTREAM OUTPUTAny output device and any file

Individual data values are written with PUT statements that convert the values to character strings and automatically format the strings into lines, or records. A PUT statement can fill part or all of one or more lines. Data conversion and alignment within lines can use the default processing provided by the PUT LIST form of the PUT statement or can be explicitly controlled by format specifications in the PUT EDIT form of the PUT statement. The output fields can be aligned to specific tab positions.

The PAGESIZE and LINESIZE options can be specified to control the formatting of lines on pages. The ENDPAGE condition is signaled when the end- of-page is reached.

STREAM INPUT

Any input device and any fileIndividual data items are read by GET statements. A single GET statement can process all or part of one or more lines or records. The format of an input field can be determined by the default processing provided by the GET LIST form of the GET statement or can be explicitly controlled by format specifications in the GET EDIT form of the GET statement.
STREAM OUTPUT

Any output device and any fileThis form of stream output is similar to that provided when PRINT is specified, except that tab positioning and page formatting are not provided. Moreover, when string values are written with the PUT LIST form of the PUT statement, they are enclosed in apostrophes. Files that are created with these attributes can be read back in with GET LIST statements when the file is opened with the STREAM and INPUT attributes.

Successive GET statements acquire their input from the same line or record until all the characters in the line have been read, unless the program explicitly skips to the next line. When necessary, a single GET statement will read multiple lines to satisfy its input-target list. A single input data item cannot cross a line unless it is a character string enclosed in apostrophes or unless the ENVIRONMENT option IGNORE_LINE_MARKS is in effect for the input file. This option produces stream input operations that match exactly with standard PL/I. However, the option is usually not necessary; most programs produce the expected results without it. (For more information on ENVIRONMENT, see the Endless PL/I for POSIX Systems User's Manual.

Successive PUT statements write their output to the same line or record until the line size is reached or until the program explicitly skips to a new line. A single PUT statement will write as many records as necessary to satisfy its output-source list. Any single data item that will not fit on the current line is split across lines.

The next sections describe the following aspects of stream I/O:

  • Processing and Positioning of Stream Files

  • Input by the GET statements.

  • Output by the PUT statements.

  • Format items

  • Processing and Positioning of Character Strings

  • Terminal I/O

9.2.1. Processing and Positioning of Stream Files

A stream file is a file of ASCII text, divided into lines. For every stream file used in a program, PL/I maintains the following information:

  • The locations of the beginning and end of the file. On input operations, the ENDFILE condition is signaled on the first attempt to read past the end of the file.

  • For output files, the maximum number of ASCII characters in a line, or the line size. The line size is either a default value or the specific value you have established for the file (see Section 9.1, “Opening and Closing Files” for LINESIZE option). The line size is used to determine when to skip to the next line. On input, a single data item cannot cross a line unless it is a character string enclosed in apostrophes or unless the file was opened with ENVIRONMENT (IGNORE_LINE_MARKS). On output, data items are continued on the next line.

  • The current position in the file. Essentially, this is the point in the file at which the last input or output operation stopped. It is the exact character position at which the next output item is written or from which the next input item is read.

Input operations can begin at any position from the current position onward. The default is the current position. To acquire data from a different position, do the following:

  • Use the SKIP option of the GET statement to advance by a specified number of lines before reading data.

  • Use control format items to move to a specified position before reading data. The GET statement restricts control format items to SKIP (the same operation as the SKIP option), COLUMN (advance to a specified character position), and X (advance by a specified number of character positions from the current position). Note that the control format items, unlike the SKIP option, are executed during, not before, the input of data. The control format items can signal the ENDFILE and ERROR conditions if the end-of-file is encountered.

  • Close and then reopen the file, which sets the current position to the first character in the file.

Because stream files are sequential files, output operations always place data at the end of the file. Do the following additional formatting of output with any stream output file:

  • Use the SKIP option of the PUT statement to skip lines following the current position. If the current position is the beginning of a line, the SKIP option inserts null lines in the file between the current position and the position of the next output.

  • Use the control format items to advance to a specified line or character position. The control format items are COLUMN (move to a specified character position), SKIP (the same effect as the SKIP option), and X (skip a specified number of characters following the current position). As with the input case, control format items execute only during the output of data; if only part of the format list is used, the excess control format items are ignored.

If the output file is a print file (that is, has the attributes STREAM, OUTPUT, and PRINT, or is the default file SYSPRINT), the following additional information is maintained for the file:

  • The current page number. The first output to a print file is written to page 1. The current page number is incremented by the PAGE option, the PAGE format item, and, in some circumstances, by the LINE option and LINE format item. You can evaluate the current page number for a specified print file with the PAGENO built-in function. You can also set it to a new value by assigning a value to the PAGENO pseudovariable.

  • The page size. This is an integer that specifies the number of lines on a page. The page size is either the default value or the specific number that you have established for the print file (see Section 9.1, “Opening and Closing Files”). When the last line on a page is filled, the first attempt to write (or position the file) beyond that position signals the ENDPAGE condition. The ENDPAGE condition is signaled only on the first such attempt; if no ON-unit is established for the condition, a PUT PAGE is executed. For example, the ON-unit for the ENDPAGE condition can write a trailer at the bottom of the current page, or a header at the top of the next page, before printing a new page of data.

  • The current line number. This is an integer specifying the line currently being used for output, relative to the top of the page. The first line on the page is line 1. The LINENO built-in function can evaluate the current line of a specified print file. The LINE option of the PUT statement, and the LINE format item, can reposition the file to a specified line.

  • Position of tab stops. Tab stops always occur at 8-column increments on every line of a print file, beginning with column 1. The TAB format item can reposition a print file to a specified tab stop relative to the current position.

Terminals should always be declared as print files when used for output (see Section 9.2.6, “Terminal I/O”.)

9.2.2. Input by the GET Statement

The GET statement acquires data from an input stream, which is either a stream file or a character-string expression. The input file can be a file declared with the STREAM attribute or the default file SYSIN, usually associated with the user's default input device. See Section 9.2.6, “Terminal I/O” for more information.

This section describes the syntax, options, and execution of GET statements.

9.2.2.1. Syntax Summary of the GET Statement

The GET statement has several forms, as follows:

GET EDIT (input-target*, ...) (format-specification, ...)
[ FILE(file-reference)*           ] ;
[       [SKIP[(expression)]]*     ]
[       [OPTIONS(option, ...)]*   ]
[ STRING(expression)*             ]
GET LIST (input-target*, ...)
[ FILE(file-reference)*          ] ;
[       [SKIP[(expression)]]*    ]
[       [OPTIONS(option, ...)]*  ]
[ STRING(expression)*            ]
GET [FILE(file-reference)]* SKIP [(expression)] ;
Options* (dec and ansi dialects only)
NO_ECHO
NO_FILTER
PROMPT(expression)
PURGE_TYPE_AHEAD

*Syntax elements common to two or more forms

input-target

The names of one or more variables to be assigned values from the input stream. Multiple input targets must be separated by commas.

An input target has one of the following forms:

reference

The reference is to a scalar or aggregate variable of any computational type. If the reference is to an array, data is assigned to array elements in row- major order. If the reference is to a structure, data is assigned to structure members in the order of their declaration.

(input-target, ... DO reference=expression [TO expression]
[BY expression] [WHILE(expression)] [UNTIL(expression)])

Another form is:

(input-target, ... DO reference=expression
[REPEAT expression] [WHILE(expression)] [UNTIL(expression)])

The input target can be any of these forms, and the references and expressions are as for the DO statement. Notice that the parentheses surrounding the input target are in addition to the parentheses surrounding the entire input list.

For a discussion of the matching of format items to input targets and of the use of DO specifications, see Section 9.2.4.13, “Format Specifications”.

format-specification

A list of format items to control the conversion of data items in the input list. You can use data format items, control format items, or remote format items. For each variable name in the input-target list, there is a corresponding data format item in the format-specification list that specifies the width of the field and controls the data conversion. See Section 9.2.4, “Format Items” for more information.

FILE (file-reference)

An option specifying that the input stream is a file; the reference is to a declared file variable or constant. If neither the FILE option nor the STRING option is specified, PL/I assumes the file SYSIN. This file is associated with the default system input file SYS$INPUT.

If a file is specified and is not currently open, PL/I opens it with the attributes STREAM and INPUT. The UNDEFINEDFILE condition is signaled if the file cannot be opened.

SKIP [(expression)]

An option that advances the input file a specified number of lines before processing the input list. This option can be used only with the implied or explicit FILE option. If the expression is specified, it indicates the number of lines to be advanced; if it is omitted, the default is to skip to the next line. The SKIP option is always executed first, before any other input or positioning of the input file, regardless of its position in the statement.

OPTIONS (option, ...) (dec and ansi dialect only)

An option that specifies one or more of the following options. This option can be used only with the default or explicit FILE option; it cannot be used with the STRING option. Multiple options must be separated by commas.

CANCEL_CONTROL_O

NO_ECHO

NO_FILTER

PROMPT (string-expression)

PURGE_TYPE_AHEAD

The options are described fully in the Endless PL/I for POSIX Systems User's Manual.

STRING(expression)

An option specifying that the input stream is a character-string expression. The STRING option cannot be used with the FILE, OPTIONS, or SKIP option.

The GET STRING statement acquires a string from a character-string variable and assigns it to one or more input targets. If more than one input target is listed, the characters in the string should include any punctuation (comma or space separators or apostrophes) that would be required if the character string were in an external file.

9.2.2.2. GET EDIT

The GET EDIT statement acquires fields of character-string data from an input stream, which can be a stream file or a character-string expression. The stream file can be a declared file or the default file SYSIN. GET EDIT converts the character strings under control of a format specification and assigns the resulting values to a specified list of input targets (variables). It also allows input of characters from selected positions in the input stream.

The form of the GET EDIT statement is as follows:

GET EDIT (input-target, ...) (format-specification, ...)
[ FILE(file-reference)          ] ;
[       [SKIP[(expression)]]    ]
[       [OPTIONS(option, ...)]  ]
[ STRING(expression)            ]

The syntax is described in more detail in Section 9.2.2.1, “Syntax Summary of the GET Statement”.

Examples
GET EDIT (FIRST,MID_INITIAL,LAST) (A(12),A(1),A(20));

This statement reads the next 12 characters from the default stream input file (SYSIN) and assigns the string to FIRST. It then reads the next character into MID_INITIAL, and then the next 20 characters into LAST.

GET EDIT (SOCIAL_SECURITY) (A(12))
       FILE (SOCIAL) SKIP (12);

This statement opens the stream file SOCIAL if the file was closed, advances 12 lines, reads the first 12 characters of the line, and assigns the characters to the variable SOCIAL_SECURITY.

GET EDIT (N, (A(I) DO I=1 TO N))
       (F(4),SKIP,100 F(10,5));

where the dimension of A is less than or equal to 100. This reads the value of N from the input stream using the format item F(4). The process then skips to the next line (record). It reads N elements into the array A, using the format item F(10,5) for each element.

GET EDIT (NAME.FIRST,NAME.LAST)
       (A(10),X(3),A(20))
       STRING('Philip    A. Rothberg            ');

This statement assigns `Philip ' to the structure member NAME.FIRST, skips the middle initial, period, and space, and assigns `Rothberg ' to NAME.LAST.

9.2.2.3. GET LIST

The GET LIST statement acquires character-string data from an input stream, which can be a stream file or a character-string expression. The stream file can be a declared file or the default file SYSIN. The acquired character strings are assigned to input targets named in the GET LIST statement, after being converted automatically to the target data types.

Use the GET LIST statement to read unformatted data from a stream file or character string. Because GET LIST does not require that data be aligned in specific columns, it is useful for acquiring input from a terminal.

The form of the GET LIST statement is as follows:

GET LIST (input-target, ...)
[ FILE(file-reference)          ];
[       [SKIP[(expression)]]    ]
[       [OPTIONS(option, ...)]  ]
[ STRING(expression)            ]

The syntax is described in more detail in Section 9.2.2.1, “Syntax Summary of the GET Statement”.

Specifying Input Data

The items to be read into the input targets are separated by a space or a single comma. Multiple spaces are treated as a single space, and a comma can be surrounded by spaces. The following rules apply:

  • No items can be split across lines unless the split occurs inside a quoted string.

  • Character strings do not have to be enclosed in apostrophes unless they contain a space or comma or are written on more than one line. When a character string is enclosed in apostrophes, n apostrophes within the string are written as n * 2 apostrophes; for instance, the word isn't would be specified as either:

isn't or 'isn''t'
  • When a line begins with a comma or when two commas appear in the line without intervening nonspace characters, the item in the input-target list corresponding to that item is not updated. The target retains whatever value it contained before GET LIST was executed.

  • Every input field, including the last input field in a line, must be terminated by a space, a comma, or a carriage return.

  • Input fields are also terminated by the end-of-file (FILE option) or end-of-string (STRING option), unless the end is encountered inside a quoted string.

  • If an input request from GET LIST encounters a null record, the null character string ('') is assigned, with appropriate conversion, to the corresponding input target. A null input record means a null record in a file or, if the input is from a terminal, a carriage return with no other input. See Section 9.2.6, “Terminal I/O” for examples. ENVIRONMENT (IGNORE_LINE_MARKS) is used for the input file, record terminators such as the carriage return are ignored, and the GET LIST statement waits until the input request is satisfied.

  • The CONVERSION condition is signaled whenever a data item in the stream cannot be converted to the data type of the corresponding item in the input-target list.

  • The ENDFILE condition is signaled if the end of the file is encountered during file input. The ERROR condition is signaled if the expression in the STRING option does not contain enough characters to complete processing of the input-target list.

Examples
GETS: PROCEDURE OPTIONS(MAIN);

DECLARE NAME CHARACTER(80) VARYING;
DECLARE AGE FIXED;
DECLARE (WEIGHT,HEIGHT) FIXED DECIMAL(5,2);
DECLARE SALARY PICTURE '$$$$$$V.$$';
DECLARE DOSAGE FLOAT;

DECLARE INFILE STREAM INPUT FILE;
DECLARE OUTFILE PRINT FILE;

GET FILE(INFILE)
       LIST(NAME,AGE,WEIGHT,HEIGHT,SALARY,DOSAGE);
PUT FILE(OUTFILE)
       LIST(NAME,AGE,WEIGHT,HEIGHT,SALARY,DOSAGE);
END GETS;

If the file INFILE.DAT contains the following data:

'Thomas R. Dooley',33,150.60,5.87,15000.50,4E-6,

then the program GETS writes the following output to OUTFILE.DAT:

Thomas R. Dooley 33 150.60 5.87 $15000.50 4.0000000E-06

In the input file (INFILE.DAT), the string `Thomas R. Dooley' is surrounded by apostrophes so PL/I will not interpret the spaces between words as field separators.

GSTR: PROCEDURE OPTIONS(MAIN);

DECLARE STREXP CHARACTER(80) VARYING;
DECLARE (A,B,C,D,E) FIXED;
DECLARE OUTFILE STREAM OUTPUT FILE;

OPEN FILE(OUTFILE) TITLE('GSTR.OUT');
STREXP = '1,2,3,4,5';
GET STRING(STREXP) LIST(A,B,C,D,E);
PUT FILE(OUTFILE) LIST(A,B,C,D,E);
END GSTR;

The program GSTR writes the following output to GSTR.OUT:

1       2       3       4       5

For other examples, see Section 9.2.6, “Terminal I/O”.

9.2.2.4. GET SKIP

The GET SKIP statement positions the input file at the start of a new line. The format of this GET statement is as follows:

GET [FILE(file-reference)] SKIP [(expression)] ;

The syntax is described in more detail in Section 9.2.2.1, “Syntax Summary of the GET Statement”.

9.2.2.5. Execution of the GET Statement

When a GET statement is executed, the first action is to evaluate the FILE option, if there is one. For example:

GET FILE(INFILE) LIST(A);

If INFILE references an open file, PL/I checks that the file has the INPUT and STREAM attributes.

If INFILE has not been opened, PL/I implicitly opens the file with the attributes INPUT and STREAM.

If the associated file does not exist, or if for any reason the associated file cannot be opened, the UNDEFINEDFILE condition is signaled.

If the statement has a STRING option instead of a FILE option, the reference in the STRING option is evaluated.

If the statement has neither a FILE option nor a STRING option, it is taken to refer to the default file constant SYSIN. SYSIN is declared by default with the STREAM INPUT attributes, and it is normally used for input from a terminal (see Section 9.2.6, “Terminal I/O”).

If the input stream is a file, the next action is to execute the SKIP option, if there is one. The SKIP option cannot be used with the STRING option. Note that a GET statement can perform a SKIP operation even if it performs no data input. For example:

GET FILE(INFILE) SKIP(2);

This statement repositions the file referenced by INFILE to the second line following the current line in the file.

A GET statement that has the EDIT or LIST option performs input from the stream to a list of input targets, which must be variables of computational data types. If the input target is an aggregate variable, then input is assigned to each element of the aggregate; input values are assigned to array elements in row- major order and to structure members in the order of their declaration. An input target can also contain a DO construct that further controls the assignment. Because a stream consists only of ASCII characters, and the input targets are not necessarily character-string variables, an input field must be selected from the input stream for each target and must be converted, if necessary, to the type of the target.

In edit-directed (GET EDIT) statements, the selection and assignment of the input field are controlled by a format item that corresponds to the input target. In the default case, which applies to terminal input and to input from most stream files, a data format item assumes that the end of the input field has occurred if it encounters the end of a record in an input file or the end of a line when the input is from a terminal.

For example, a common technique for reading lines of varying length from a terminal is to deliberately use a format item that specifies a field wider than the column width of the terminal. If the user types a carriage return in response to an input request for GET EDIT, or if the end of a record is immediately encountered, the requested field width is filled with spaces and assigned to the input target under the control of the corresponding format item. (Note that all spaces will cause an error for B format items.) However, if the input stream is a character-string expression (GET STRING), the ERROR condition is signaled if the format item causes the end of the input string to be reached in the middle of an input field. If the input stream is a file declared or opened with ENVIRONMENT(IGNORE_LINE_MARKS), the search for characters to complete the input field continues at the next record.

In list-directed (GET LIST) statements, an input field is acquired by examining the input stream for the next character that is not a space character.

The following actions are taken depending on the character found:

  • If the next nonspace character is an apostrophe, the input field is assumed to contain a bit- or character-string constant, in the same format as that used to write a string constant in a program. The constant is acquired and can span the end of a record or line. However, the ERROR condition is signaled if the end of the file is reached before the terminating apostrophe is found; if the input stream is a character-string expression rather than a file, the ERROR condition is signaled if the end of the string is reached. The apostrophes and B suffix are removed from the constant, and any double apostrophe within a character-string constant is changed to a single apostrophe. (If the field contains a bit-string constant in base 4, octal, or hexadecimal radix, its binary equivalent is found.) The resulting character bit-string value is then assigned to the corresponding input target. If the input target is not of the same data type, the input value is converted according to the PL/I conversion rules (see Section 6.4, “Data Type Conversion of Operands and Expressions”).

  • If the next nonspace character is a comma, and the previous operation on the input file was by GET LIST, and the previous input field was terminated by a space, carriage return, or end-of-record, the scan continues. If the next nonspace character is a comma, and the previous nonspace character was also a comma, the corresponding input target is skipped; the input target retains whatever value it had before the GET LIST statement.

  • If the input line or record is empty (that is, a carriage return or end-of-record is encountered immediately after the beginning of a line). The null character string ('') is assigned to the input target with appropriate type conversion. If the input file was opened with ENVIRONMENT(IGNORE_LINE_MARKS), the carriage return or end-of-record is ignored.

  • If the next nonspace character is neither a comma nor an apostrophe, the input field is then assumed to begin with this character and to be terminated by the next space, comma, carriage return, end-of-record (if ENVIRONMENT(IGNORE_LINE_MARKS) was not used), end-of-file (if the input stream is a file), or end-of-string (if the input stream is a character string). All the characters in the field are acquired and assigned, with appropriate type conversion, to the input target.

If the GET LIST statement attempts to read a file after its last input field has been read, or if it attempts to read an empty file, the ENDFILE condition is signaled. If the GET LIST statement attempts to read a character string after its last field has been read, or if it attempts to read a null string, the ERROR condition is signaled.

9.2.3. Output by the PUT Statement

The PUT statement transfers data from the program to the output stream. The output stream can be either a stream file or a character-string variable. The output file can be a declared file or the default file SYSPRINT.

This entry describes the syntax, options, and execution of PUT statements.

9.2.3.1. Syntax Summary of the PUT Statement

The PUT statement has several forms, as follows:

PUT EDIT (output-source*, ...) (format-specification, ...)
[ FILE(file-reference)*               ] ;
[       [PAGE]*                       ]
[       [LINE (expression)]*          ]
[       [SKIP[(expression)]]*         ]
[       [OPTIONS(option, ...)]*       ]
[ STRING(reference)*                  ]
PUT [FILE (file-reference)*] LINE (expression);
PUT LIST (output-source,)*
[ FILE(file-reference)*                   ] ;
[       [PAGE]*[LINE (expression)]*       ]
[       [SKIP[(expression)]]*             ]
[       [OPTIONS(option, ...)]*           ]
[ STRING(reference)*                      ]
PUT [FILE (file-reference)*] PAGE;
PUT [FILE (file-reference)*] SKIP [(expression)] ;

*Syntax elements common to two or more forms

output-source

A construct that specifies one or more expressions to be placed in the output stream. Multiple output sources must be separated by commas.

An output source has the following forms:

expression

The expression is of any computational type, including a reference to a scalar or aggregate variable. If the reference is to an array, data is output from array elements in row-major order. If the reference is to a structure, data is output from structure members in the order of their declaration.

(output-source, ...DO reference=expression
[TO expression][BY expression] [WHILE(expression)] [UNTIL(expression)])

Another form is:

(output-source, ...DO reference=expression
[REPEAT expression][WHILE (expression)][UNTIL(expression)])

The output source can be any of these forms, and the references and expressions are as for the DO statement. Notice that the parentheses surrounding this form of output source are in addition to the parentheses surrounding the entire output- source list.

For a discussion of the matching of format items to output sources and of the use of DO specifications, see Section 9.2.4.13, “Format Specifications”.

format-specification

A list of format items to control the conversion of data items in the output list. Format items can be data format items, control format items, or remote format items. For each variable name in the output-source list, there is a corresponding data format item in the format-specification list that specifies the width of the output field and controls the data conversion (see Section 9.2.4.13, “Format Specifications” and Section 9.2.4, “Format Items”).

FILE(file-reference)

An option that specifies that the output stream be a stream file; the reference is to a declared file variable or constant. If neither the FILE option nor the STRING option is specified, PL/I uses the default file SYSPRINT. SYSPRINT is associated with the default system output file SYS$OUTPUT, which in turn is generally associated with the user's terminal.

If a file is specified, and it is not currently open, PL/I opens the file with the attributes STREAM and OUTPUT.

PAGE

An option that advances the output file to a new page before any data is transmitted. The PAGE option can be used only with implied or explicit print files. The file is positioned at the beginning of the next page, and the current page number is incremented by 1. The PAGE, LINE, and SKIP options are always executed, in that order, before any other output or file-positioning operations. The page size is either the default value or the specific value that you have established for the file (See Section 9.1.3, “Opening a File”). The PAGESIZE option can be used only with print files.

LINE (expression)

An option that advances the output file to a specified line. You can use the LINE option only with implied or explicit print files. The expression must yield an integer i. Blank lines are inserted in the output file such that the next output data appears on the ith line of a page.

If the file is currently positioned at the beginning of line i, no operation is performed by the LINE option.

If the file is currently positioned before line i, and i is less than or equal to the page size, then blank lines are inserted following the current line until line i is reached.

If the file is currently positioned at or beyond line i, and the file is not at the beginning of line i, then the remainder of the page (the portion between the current line and the current page size) is filled with blank lines. The ENDPAGE condition is signaled.

When the LINE option is used within an ENDPAGE ON-unit, it causes a skip to the next page.

SKIP [(expression)]

An option that advances a specified number of lines from the current line. You can use the SKIP option only with the implied or explicit FILE option. The expression must yield an integer i, which must not be negative and must be greater than zero except for print files. If the expression is omitted, i equals 1.

If the file is not a print file, i-1 blank lines are inserted following the current line, and subsequent output of data begins at the beginning of (current line)+i.

If the file is a print file, i=0 causes a return to the beginning of the current line. If i is greater than zero, and either the current line exceeds the page size or the page size is greater than or equal to the current line plus i, then i-1 blank lines are inserted. Otherwise, the remainder of the current page is filled with blank lines, and the ENDPAGE condition is signaled.

On output devices with the space-suppression feature, SKIP(0) can be used to cause overprinting, underscoring, and so forth. For further information on pages in stream files, see Section 9.2.6, “Terminal I/O”.

OPTIONS (CANCEL_CONTROL_O)

A statement option that can be included only with the implied or explicit FILE option. The option is described fully in the Endless PL/I for POSIX Systems User's Manual.

STRING(reference)

An option that specifies that the output stream be the referenced character-string variable. The STRING option cannot be used in the same statement with FILE, OPTIONS, PAGE, LINE, or SKIP.

9.2.3.2. PUT EDIT

The PUT EDIT statement takes output sources (variables and expressions) from the program, converts the results to characters under control of a format specification, and places the resulting character strings in the output stream. The output stream is either a stream file or a character-string variable.

With PUT EDIT, the format of the output data is controlled by the program.

The form of the PUT EDIT statement is as follows:

PUT EDIT (output-source, ...) (format- specification, ...)
[ FILE(file-reference)              ] ;
[       [PAGE]*[LINE (expression)]  ]
[       [SKIP[(expression)]]        ]
[       [OPTIONS(option, ...)]      ]
[ STRING(reference)                 ]

The syntax is described in more detail in Section 9.2.3.1, “Syntax Summary of the PUT Statement”.

Examples
PUT_ED: PROCEDURE OPTIONS(MAIN);

       DECLARE SOURCE FIXED DECIMAL(7,2);
       DECLARE OUTFILE PRINT FILE;

       OPEN FILE(OUTFILE) TITLE('PUT_ED.OUT');

       SOURCE = 12345.67;

       PUT SKIP FILE(OUTFILE) EDIT(SOURCE) (F(8,2));
       PUT SKIP FILE(OUTFILE) EDIT(SOURCE) (E(13));
       PUT SKIP FILE(OUTFILE) EDIT(SOURCE) (A);
       PUT SKIP FILE(OUTFILE) EDIT('American: ',SOURCE)
               (A,P'ZZ,ZZZV.ZZ');
       PUT SKIP FILE(OUTFILE) EDIT('European: ',SOURCE)
               (A,P'ZZ.ZZZV,ZZ');

END PUT_ED;

The program PUT_ED writes the following output to PUT_ED.OUT:

12345.67
       1.234567E+04
       12345.67
American: 12,345.67
European: 12.345,67

9.2.3.3. PUT LINE

The PUT LINE statement advances a print file to a specified line. Its format is as follows:

PUT [FILE (file-reference)] LINE (expression);
file-reference

A reference to the file to which the statement applies. The file must be a print file.

The syntax is described in more detail in Section 9.2.3.1, “Syntax Summary of the PUT Statement”.

9.2.3.4. PUT LIST

The PUT LIST statement specifies a list of output sources (variables and expressions) whose results are converted to character strings and transmitted to the output stream. If the output file is a print file, the output character strings are placed at the start of the next tab stop, where a tab stop is in column 1, 9, 17, and so on. Otherwise, the strings are separated by spaces.

With PUT LIST, the conversion of the output sources and formatting of the output data are automatic and follow the PL/I rules for conversion to character strings.

The format of the PUT LIST statement is as follows:

PUT LIST (output-source, ...)
[ FILE(file-reference)                     ] ;
[       [PAGE]* [LINE (expression)]        ]
[       [SKIP[(expression)]]               ]
[       [OPTIONS(option, ...)]             ]
[ STRING(reference)                        ]

The syntax is described in more detail in Section 9.2.3.1, “Syntax Summary of the PUT Statement”.

Examples
PUTL: PROCEDURE OPTIONS(MAIN);

DECLARE I FIXED BINARY,
       F FLOAT,
       P PICTURE '99V.99',
       S CHAR(10);

DECLARE INFILE STREAM INPUT FILE;
DECLARE OUTFILE PRINT FILE;

OPEN FILE(INFILE) TITLE('PUTL.IN');
OPEN FILE(OUTFILE) TITLE('PUTL.OUT');

GET FILE(INFILE) LIST (I,F,P,S);
PUT FILE(OUTFILE) SKIP LIST (I,F,P,S);

END PUTL;

Assume that the file PUTL.IN contains the following data:

2,3.54,22.33,'A string'

Then the program PUTL writes the following output to PUTL.OUT:

2       3.5400000E+00   22.33   A string

For print files, each output item is written at the next tab position. Floating-point values are represented in floating-point notation. Character values are not enclosed in apostrophes.

9.2.3.5. PUT PAGE

The PUT PAGE statement positions the output file at the start of a new page. This statement is valid only for print files, that is, files that have been opened with the PRINT attribute.

The form of the PUT PAGE statement is:

PUT [FILE(file-reference)] PAGE;

The syntax is described in more detail in Section 9.2.3.1, “Syntax Summary of the PUT Statement”.

Example
PUT FILE(REPORT) PAGE SKIP LINE(2);

The PUT statement advances the file REPORT to the beginning of the next page, advances to line 2, and skips to the beginning of the next line (3).

9.2.3.6. PUT SKIP

The PUT SKIP statement positions the output file at the start of a new line.

The form of the PUT SKIP statement is:

PUT [FILE(file-reference)] SKIP [(expression)];

The syntax is described in more detail in Section 9.2.3.1, “Syntax Summary of the PUT Statement”.

9.2.3.7. Execution of the PUT Statement

When a PUT statement is executed, the first action is to evaluate the FILE or STRING option, if there is one. If the statement has a FILE option and is not already open, the referenced file is either opened or created with the STREAM and OUTPUT attributes. The file is opened if it has the APPEND attribute; otherwise, it is created.

If neither the FILE option nor the STRING option is present, the output stream is assumed to be the default file SYSPRINT.

If the output stream is a file, the next action is to execute any of the options PAGE, LINE, and SKIP that occur in the statement, in that order. The output stream must be a file if any of these options are included, and it must be a print file if LINE or PAGE is included. Note that a PUT statement can contain one or more of these options even if it performs no data output. For example:

PUT FILE(OUT) PAGE LINE(20);

This statement skips to a new page in the file referenced by OUT (which must be a print file), moves to line 20 of the file, and then terminates.

However, if the statement also has a LIST or EDIT option, it then writes out a list of output sources, which must be variables, constants, or other expressions of computational data types. Because a stream consists only of ASCII characters, each output source is converted to a character string before being written out, as follows:

  • If the PUT statement is list directed, the output source is converted according to the PL/I rules for converting a computational value to a character string (see Section 6.4, “Data Type Conversion of Operands and Expressions”).

  • If the PUT statement is edit directed, the output source is converted as specified by a corresponding format item. For details, see Section 9.2.4, “Format Items”.

  • If the output stream is a character-string variable or file with the attributes STREAM and OUTPUT (but not PRINT), the statement is list directed, and the output source is of type CHARACTER, the output source value is surrounded by apostrophes, and any apostrophe within the value is replaced by a double apostrophe.

  • If the output source is of type BIT, and the statement is list directed, the converted output source is surrounded by apostrophes, and the letter `B' is appended.

The converted output source is then written to the output stream, as follows:

  • If the statement is list directed and the output stream is a file with the attributes STREAM and OUTPUT (but not PRINT), then the converted output source is written beginning at the end of the file and followed by a single space. If the output stream is a print file, the converted output source is written out beginning at the end of the file, after enough spaces have been written out to move to the next tab stop. In either case, if the converted output source does not fit on the remainder of the current line, as much as possible is written on the current line, and the rest is written on the next line. The ENDPAGE condition can be signaled if the output stream is a print file. For more information on print files, see Section 9.2.6, “Terminal I/O”.

  • If the statement is edit directed, the exact number of characters specified by the format item is written out, and no space follows. As much output as possible is written on the remainder of the current line, and it is continued, if necessary, on the next line. Any additional positioning, such as on tab stops in a print file, is performed by control format items.

  • If the output stream is a character-string variable, the output process is identical to that for a STREAM OUTPUT file except that the first output source written out by a PUT statement is placed at the beginning of the variable's storage, and any previous value in the variable is erased. Note that the X format item, which can be used with PUT STRING, performs positioning by writing out spaces, not by skipping characters in the previous value of the variable. Note also that list-directed output to a character variable, followed by list-directed output of the variable itself, can result in a proliferation of apostrophes in the value finally written to a file.

9.2.4. Format Items

In PL/I, formatted input and output data is transferred with the GET EDIT and PUT EDIT statements, which include a format specification made up of format items.

PL/I format items are categorized as follows:

  • Data format items: A, B, E, F, and P

  • Remote format item: R

  • Control format items: COLUMN, LINE, PAGE, SKIP, TAB, and X

The data format items refer to a field of characters in the stream. Each data format item specifies the field width in characters and either the manner in which the field is used to represent a value (output) or the manner in which the characters in the field are to be interpreted (input). Because the representation or interpretation is under control of the format items, certain symbols used in the stream with GET LIST and PUT LIST are not used with GET EDIT or PUT EDIT:

  • Strings input by the GET EDIT statement should not be enclosed in apostrophes unless the apostrophes are intended to be part of the string. Strings output by PUT EDIT are not enclosed in apostrophes.

  • Bit strings input by the GET EDIT statement should not be enclosed in apostrophes, nor should they be followed by the radix factor B, B1, B2, B3, or B4. These factors are not added by the PUT EDIT statement on output.

  • The comma and space characters are not interpreted as data separators on input. On output, values are not automatically separated by spaces.

The following guidelines apply to errors and mismatches that occur between the actual data values and the fields specified by data format items:

  • On input, the CONVERSION condition is signaled if the field of characters cannot be interpreted as required by the format item.

  • On output, strings are left-justified in the specified field, and numeric data is right-justified. Truncation occurs if the field is too narrow to contain the necessary characters; strings are truncated on the right and numeric data on the left.

The rest of this section describes each format item in detail. The following subsections describe format-specification lists and the FORMAT statement.

9.2.4.1. A Format Item

The A format item (both uppercase and lowercase) describes the representation of a character string in the input or output stream. The form of the A format item is as follows:

A [(w)]
w

A nonnegative integer or an integer expression that specifies the width in characters of the field in the stream. If it is not included (PUT EDIT only), the field width equals the length of the converted output source.

Input with GET EDIT

The value w must be included when the A format item is used with GET EDIT. If w has a positive value, a character-string value comprising the next w characters in the input stream is acquired and assigned to the input variable.

The acquired character string is converted, if necessary, to the data type of the input target, following the PL/I data conversion rules. Apostrophes should enclose the stream data only if the apostrophes are intended to be acquired as part of the data.

Output with PUT EDIT

The output source associated with an A format item is converted, if necessary, to a string of characters. The result is assigned to a string of w characters, which are placed in the output stream. If w is omitted, the length of the output string equals the length of the converted output source. If w is zero, the A format item and the associated output source are skipped.

Output strings are not surrounded automatically by apostrophes. The converted output source is truncated or appended with trailing spaces, according to the value of w. The conversion of a computational data item to a character string is performed following the PL/I data conversion rules (see Section 6.4, “Data Type Conversion of Operands and Expressions”).

Table 9.4, “Input String Formatting” and Table 9.5, “Output String Formatting” show the relationship between the internal and external representations of characters that are read or written with the A format item.

Input Examples

In Table 9.4, “Input String Formatting”, the input stream is a field of characters beginning at the current position in the stream and continuing to the right. The # character signifies a space. The target type is the type of the variable to which the input value is assigned.

Table 9.4. Input String Formatting
Format ItemInput StreamTarget TypeTarget Value
A(10)##SHRUBBERY# ...CHAR(10)##SHRUBBER
A(6)##SHRUBBERY# ...CHAR(10)##SHRU####
A(6)##SHRUBBERY# ..CHAR(10) VAR##SHRU
A(10)##1.2345#### ...DECIMAL(4,1)001.2
A(5)##1.2345#### ...DECIMAL(4,2)01.20
A(6)##1.2345#### ...DECIMAL(4,2)01.23

Output Examples

In Table 9.5, “Output String Formatting”, the output source value is either a constant or the value of a variable that is written with the associated format item.

Table 9.5. Output String Formatting
Output Source ValueFormat ItemOutput Value
`STRING'A(10)STRING####
`STRING'ASTRING
1.2345A(2)##
1.2345A##1.2345
-1.2345A4)#-1.
-1.2345A#-1.2345
''A(10)##########
''A[no output]
0A(3)###
0A###0
-12345A(6)##-123
-12345A##-12345

9.2.4.2. B Format Items

The B format items B, B1, B2, B3, and B4 describe representations of bit strings in an input or output stream. Note that the B can be typed lowercase. The form of the B format items is as follows:

B[m] (w)
m

The integer 1, 2, 3, or 4, specifying the radix factor, that is, 2m. B and B1 have the same meaning. When the radix factor is omitted or is 1, the bit string is represented by the characters 0 and 1 (binary) in the stream. When the radix factor is 2, the bit string is represented by the characters 0, 1, 2, and 3 (base 4). When the radix factor is 3, the bit string is represented by the characters 0, 1, 2, 3, 4, 5, 6, and 7 (octal). When the radix factor is 4, the bit string is represented by the characters 0 through 9 and A through F (hexadecimal).

w

A nonnegative integer or integer expression that specifies the width in characters of the field in the stream.

The interpretation of the B format items on input and output is described below.

Input with GET EDIT

The value w must be included when the B format items are used with GET EDIT. The number of characters specified by w is acquired. The input characters are converted to an intermediate bit string of length w*m. If the input target is not a bit-string variable, then this intermediate bit string is converted to the type of the input target, following the PL/I conversion rules (for details, see Section 6.4, “Data Type Conversion of Operands and Expressions”).

The string of characters in the stream can be preceded or followed by spaces, which are ignored. All characters in the input field (except any leading and trailing spaces) must be those implied by the radix factor; otherwise, a CONVERSION condition is signaled. Consequently, input strings should not be enclosed in apostrophes and should not include the suffix Bm.

Output with PUT EDIT

The output source is converted, if necessary, to a bit string, following the PL/I rules for converting data to bit strings (see Section 6.4, “Data Type Conversion of Operands and Expressions”). If the length of the resulting bit string is not a multiple of the radix factor (m), the bit string is padded with zeros on the right to make its length the next higher multiple.

The bit string is then converted to a character representation appropriate to the radix factor and placed in the output stream. The character representation is left- justified in the field specified by w and truncated or padded with spaces on the right if necessary. If w is unspecified, the output string length is equal to the converted output source. If w is zero, the B format item and its associated output source are skipped.

Examples
BFORMAT_XM: PROCEDURE OPTIONS(MAIN);
/* This program prints incorrect values for an integer */
DECLARE I FIXED BINARY(31);
DECLARE BFORM STREAM OUTPUT PRINT FILE;
I = 5;
OPEN FILE(BFORM) TITLE('BFORMXM.OUT');
PUT SKIP FILE(BFORM) EDIT ('Decimal:',I) (A,X,F(2));
PUT SKIP FILE(BFORM) EDIT ('Binary:',I) (A,X,B);
PUT SKIP FILE(BFORM) EDIT ('Base 4:',I) (A,X,B2);
PUT SKIP FILE(BFORM) EDIT ('Octal:',I) (A,X,B3);
PUT SKIP FILE(BFORM) EDIT ('Hexadecimal:',I) (A,X,B4);
END BFORMAT_XM;

This program produces the following output:

Decimal: 5
Binary: 0000000000000000000000000000101
Base 4: 0000000000000022
Octal: 00000000024
Hexadecimal: 0000000A

The base 4, octal, and hexadecimal representations of I are incorrect because the precision of I (31) is not a multiple of 2, 3, or 4. For the B2 and B4 format items, an extra zero bit was appended to the intermediate bit string, in effect multiplying the value of the string by 2. For B3, two extra bits were appended to make the string 33 bits long and thus divisible into an exact number of 3-bit segments. To avoid this problem, the precision of the output source must be a number that is evenly divisible by any radix factor with which it is to be written out, as in the following example:

BFORMAT_XM: PROCEDURE OPTIONS(MAIN);

/* This program prints correct values for an integer */
       DECLARE I FIXED BINARY(24);
       /* 24 is a multiple of 2*3*4 */
       DECLARE BFORM STREAM OUTPUT PRINT FILE;

       I = 5;
       OPEN FILE(BFORM) TITLE('BFORMXM5.OUT');

       PUT SKIP FILE(BFORM) EDIT ('Decimal:',I) (A,X,F(2));
       PUT SKIP FILE(BFORM) EDIT ('Binary:',I) (A,X,B);
       PUT SKIP FILE(BFORM) EDIT ('Base 4:',I) (A,X,B2);
       PUT SKIP FILE(BFORM) EDIT ('Octal:',I) (A,X,B3);
       PUT SKIP FILE(BFORM) EDIT ('Hexadecimal:',I) (A,X,B4);

END BFORMAT_XM;

This version of the program produces the following output:

Decimal: 5
Binary: 000000000000000000000101
Base 4: 000000000011
Octal: 00000005
Hexadecimal: 000005

The output values are correct representations of I because the precision (24) is evenly divisible by 2, 3, or 4.

The tables below show the relationship between the internal and external representations of characters that are read or written with the B format item.

Input Examples

In Table 9.6, “Input with the B Format Item”, the input stream is a field of characters beginning at the current position in the stream and continuing to the right. The # characters signify spaces. The target type is the type of the variable to which the input value is assigned.

Table 9.6. Input with the B Format Item
Format ItemInput StreamTarget TypeTarget Value
B(12)111000111110...BIT(12)'111000111110'B
B(12)######110011...BIT(12)'110011000000'B
B2(6)123123...BIT(12)'011011011011'B
B3(4)1775...BIT(12)'001111111101'B
B4(3)1FA...BIT(12)'000111111010'B

Output Examples

In Table 9.7, “Output with the B Format Item”, the output source is either a constant or the value of a variable written out with the associated format item.

Table 9.7. Output with the B Format Item
Output Source ValueFormat ItemOutput Value
4095B111111111111
4095B(11)11111111111
4095B2333333
4095B37777
4095B4FFF

9.2.4.3. COLUMN Format item

The COLUMN format item sets a stream file to a specific character position within a line. In other words, COLUMN determines the position at which the next data will be output or from which the next data will be input. The COLUMN format item refers to an absolute character position in a line; for information on how to refer to a relative position, see Section 9.2.4.12, “X Format Item”.

The form of the COLUMN format item is:

{ COLUMN } w
{ COL    }
w

A nonnegative integer or expression that identifies the wth position from the beginning of the current line. The value of the converted expression must be zero or positive. If the value of the converted expression is zero, a value of 1 is assumed.

If the file is already at the specified position, no operation is performed. If the file is already beyond the specified position, the format item is applied to the next line.

The interpretation of the COLUMN format item on input and output is given below.

Input with GET EDIT

The file is positioned at the column specified by w. Characters between the beginning of the line and this column are ignored. If the file is already positioned beyond the specified column, the remainder of the line is skipped and the format item is applied to the next line.

Output with PUT EDIT

The file is positioned at the column specified by w. Within the current line, positions between the wth column and the position of the last output data are filled with spaces.

If the file is already positioned beyond the specified column, the format item is applied to the next line. If w exceeds the line size, a value of 1 is assumed. See Section 9.1, “Opening and Closing Files”.

Examples
COL: PROCEDURE OPTIONS(MAIN);

       DECLARE IN STREAM INPUT FILE;
       DECLARE OUT STREAM OUTPUT FILE;
       DECLARE LETTER CHARACTER(1);

       PUT FILE(OUT) SKIP
               EDIT('123456789012345678901234567890') (A);
       PUT FILE(OUT) SKIP
               EDIT('COL1','COL28') (A,COL(28),A);

       GET FILE(IN) EDIT (LETTER) (A(1));
       PUT FILE(OUT) SKIP(2)
               LIST('Letter in column 1:',LETTER);

       GET FILE(IN)
               EDIT (LETTER) (COL(25),A(1));
       PUT FILE(OUT) SKIP
               LIST ('Letter in column 25:',LETTER);

END COL;

If the stream input file IN.DAT contains the following text:

ABCDEFGHIJKLMNOPQRSTUVWXYZ

then the program COL writes the following output to the stream output file OUT.DAT:

123456789012345678901234567890
COL1                       COL28
'Letter in column 1:' 'A'
'Letter in column 25:' 'Y'

9.2.4.4. E Format Item

The E format item describes the representation of a fixed- or floating-point value as a decimal floating-point number in a stream.

The form of the item is:

E(w[,d])
w

A nonnegative integer or expression that specifies the total width in characters of the field in the stream.

d

An optional nonnegative integer or expression that specifies the number of fractional digits in the stream representation and whose value is interpreted depending on GET EDIT and PUT EDIT statements as described below.

Input with GET EDIT

Used with GET EDIT, the E format item acquires a character-string value representing a floating-point decimal value and assigns it, with necessary conversions, to an input target of any computational type. If w is zero, no operation is performed on the input stream, and a null character string is converted and assigned to the input target.

For input, floating-point values can be represented in the stream in the forms listed in Table 9.8, “Representation of Floating-Point Values”.

Table 9.8. Representation of Floating-Point Values
FormExample
mantissa124333
sign mantissa-123.333
sign mantissa sign exponent-123.333-12
sign mantissa E exponent-123.333E12
sign mantissa E sign exponent-123.343E-12

The mantissa is a fixed-point decimal constant, the sign is a plus (+) or minus (-) symbol, and the exponent is a decimal integer. A zero exponent is assumed if both the letter E and the exponent are omitted.

If, on input, the mantissa includes a decimal point, it overrides the specification of d. If no decimal point is included, then d specifies the number of fractional digits.

The value of w should be large enough to include the mantissa, the optional decimal point in the mantissa, the signs on the exponent and mantissa, the optional letter E, and the exponent. If the field width is too narrow, the stream representation is truncated on the right; if the field width is too wide, excess characters are acquired on the right and may contain invalid input.

Spaces can precede or follow the value in the stream and are ignored. If the entire field contains spaces, zero is assigned to the input target. If the stream representation is not one of the acceptable forms, an ERROR condition is signaled.

Output with PUT EDIT

Used in a PUT EDIT statement, the E format item converts an output source of any computational type to the following form for representation in the stream:

[-] digit . [fractional-digits] E sign exponent

Typical representations are as follows:

1.E+07
3.33E-10
-2.7186E+00

If d is omitted from the format item, then d = s -1, where s is the precision of the output source expressed in decimal. The decimal value is rounded before being written out.

The exponent is ordinarily a 2-digit decimal integer (for S_floating data) or a 3-digit decimal integer (for T_floating data) and is always signed. The exponent is adjusted so that the first digit of the mantissa is not zero, except that the value 0 is represented as:

0.0000 ... E+00

with a number of zeros to the right of the decimal point equal to the specified number of fractional digits.

To account for negative values with fractional digits, the specified width integer should be 7 greater than the number of digits to be represented in the mantissa: one character for the preceding minus sign, one for the decimal point in the mantissa, one for the letter E, one for the sign of the exponent, and two (or three) for the exponent itself.

If the number's representation is shorter than the specified field, the representation is right-justified in the field and the number is extended on the left with spaces.

If the field specified by w is too narrow, an ERROR condition is signaled.

Examples

The next tables show the relationship between the internal and external representations of numbers that are read or written with the E format item.

Input Examples

Table 9.9, “Input with the E Format Item” shows an input stream that is a field of characters beginning at the current position in the stream and continuing to the right. The target type is the type of the variable to which the input value is assigned.

Table 9.9. Input with the E Format Item
Format ItemInput StreamTarget TypeTarget Value
E(6,0)124333...DECIMAL(10,2)124333.00
E(6,0)-123333...DECIMAL(10,2)-12333.00
E(8)-123.333...DECIMAL(8,5)-123.33300
E(11)-123.333-12...FLOAT DEC(7)-1.233330E-10
E(11,3)-123343E-12...FLOAT DEC(15)-1.23343000000000E-10

Output Examples

The output source value shown in Table 9.10, “Output with the E Format Item” is either a constant or the value of a variable that is written out with the associated format item. The # character is used to signify a space.

Table 9.10. Output with the E Format Item
Output Source ValueFormat ItemOutput Value
-12234E(11)-1.2234E+04
-12234E(11,2)##-1.22E+04
12234E(11)#1.2234E+04
12234E(11,2)###1.22E+04
-12.234E(11,1)###-1.2E+01
-1.23456E3E(12)-1.23456E+03
-1.23456E3E(12,2)###-1.23E+03

9.2.4.5. F Format Item

The F format item describes the representation of a fixed- or floating-point value as a decimal fixed-point number in a stream.

The form of the item is:

F(w[,d])
w

A nonnegative integer or expression that specifies the total width in characters of the field in the stream.

d

An optional nonnegative integer or expression that specifies the number of fractional digits in the stream representation and whose value is interpreted depending on GET EDIT and PUT EDIT statements as described below.

Input with GET EDIT

Used with GET EDIT, the F format item acquires a fixed-point decimal value from the next w characters in the stream and converts it to an input target of any computational type. Fixed-point decimal values can be represented in the stream in the following forms:

number
sign number

The number is a fixed-point decimal constant, and the sign is a plus (+) or minus (-) symbol.

The following are valid representations:

124333

-123333

-123.

A CONVERSION condition is signaled if the field is not blank and does not contain a valid representation; otherwise, the fixed-point decimal number is extracted from the field and is assigned to the input target, with any necessary conversions. A decimal point included in the number overrides the specification of d. If no decimal point is included, d specifies the number of fractional digits. If d is omitted, it is assumed to be zero.

The value w should be only large enough to include the number, the optional decimal point in the number, and the optional sign. If w is too small, the stream representation is truncated on the right. If w is too large, extra characters, which might include invalid syntax, are acquired.

If w is zero, a null character string is converted and assigned to the input target, and no operation is performed on the stream.

Spaces can precede or follow the number in the stream and are ignored. If the entire string contains spaces or is a null string, the fixed-point decimal constant 0 is converted and assigned to the input target.

Output with PUT EDIT

Used in a PUT EDIT statement, the F format item converts an output source of any computational type to one of the following forms for representation in the stream:

integer
integer.fractional-digits
-integer.fractional-digits

Typical representations are:

3234
0.23432
3.33
-3234.33

The decimal value is rounded before being written out. If d is omitted from the format item, the decimal point is not shown, and only the integral part of the number is shown.

If d is larger than the number of fractional digits to be output, trailing zeros are appended to the output number. All leading zeros to the left of the decimal point are suppressed unless the integral part of the number is zero, in which case one zero appears to the left of the decimal point.

To account for negative values with fractional digits, the specified width integer should be 2 greater than the number of digits to be represented: one character for the preceding minus sign and one for the decimal point in the number.

If the number's representation is shorter than the specified field, the representation is right-justified in the field, and the number is extended on the left with spaces.

If the field is too narrow to represent the integral portion of the output number, an ERROR condition is signaled.

Examples

The tables below show the relationship between the internal and external representations of numbers that are read or written with the F format item.

Input Examples

Table 9.11, “Input with the F Format Item” shows an input stream that is a field of characters beginning at the current position in the stream and continuing to the right. The target type is the type of the variable to which the input value is assigned.

Table 9.11. Input with the F Format Item
Format ItemInput StreamTarget TypeTarget Value
F(10,2)-123456.78...DECIMAL(10,2)-123456.78
F(10,4)-1234.56789...DECIMAL(10,2)-1234.56
F(8,5)-.123456789...DECIMAL(5,5)-0.12345
F(10)1234.56789...FLOAT DEC(7)1.234568E+03

Output Examples

The output source value shown in Table 9.12, “Output with the F Format Item” is either a constant or the value of a variable that is written out with the associated format item. The # character is used to specify a space.

Table 9.12. Output with the F Format Item
Output Source ValueFormat ItemOutput Value
-12.234F(3,0)-12
-12.234F(6,2)-12.23
-12.234F(7,3)-12.234
-1.23456E3F(8)###-1235
-1.23456E3F(8,2)-1234.56
'1000'B3F(4)#512
'1000000000000000'BF(5)32768
'100000'B3F(5)32768
'ABCEDF'B4F(10)##11259615

9.2.4.6. LINE Format Item

The LINE format item sets a print file to a specific line. It can be used only with print files and the PUT EDIT statement. If necessary, blank lines are inserted between the current file position and the specified line, and subsequent output begins on the specified line.

The LINE format item identifies an absolute line position on the current output page; to specify a line position relative to the current line, see SKIP format item.

The form of the LINE format item is:

LINE(w)
w

An integer, or an expression, that specifies a line on the current page, where line 1 is the first line. The maximum value for a print file's line number is 32767. If a program generates a value in excess of 32767, a run-time error occurs.

When the LINE format item is executed, the current line is determined. The current line is 1 if the file is at the beginning of a new page. Otherwise, the current line is n+1, where n is the number of complete lines already on the page. The position in the file is then changed as follows:

  • If line w is the current line, and the file is either at the beginning of a new line or at the beginning of a new page, then no operation is performed.

  • If line w is beyond the current line and is less than or equal to the current page size, then the file is positioned at line w, and the lines between the current line and line w are filled with blank lines. (See Section 9.1, “Opening and Closing Files”)

  • If line w is at or before the current line, the current line is not beyond the current page size, and the file is not at the beginning of a line or page, then the remainder of the page (the portion between the current line and the current page size) is filled with blank lines, and the ENDPAGE condition is signaled. The same actions occur when the current line is less than or equal to the page size and w is greater than the page size.

  • Otherwise, the file is positioned at the beginning of a new page, and the page number is incremented by 1 (for instance, when w is zero).

9.2.4.7. P Format Item

The picture format item (P) describes a field of characters in the input or output stream. The field can be an input field acquired with GET EDIT or an output field transmitted by PUT EDIT. With GET EDIT, the P format item acquires a pictured value from the input stream. With PUT EDIT, the P format item edits an output source to a specified picture format.

The form of the P format item is:

P 'picture'
'picture'

A picture of the same syntax as for the PICTURE data attribute. The syntax is summarized in PICTURE attribute (see Section 2.2.37, “PICTURE Attribute”). The field width is the total number of characters, exclusive of V, in the picture.

The interpretation of the P format item, for input and output, is given below.

Input with GET EDIT

Used with the GET EDIT statement, the P format item acquires a pictured value (a field of characters) from the stream file, extracts its fixed-point decimal value, and assigns the value to an input target of any computational type. The picture describes a field of w characters, where w is the total number of picture characters in the picture, exclusive of the V character.

A string of w characters is acquired from the input stream and validated against the picture specified in the format item. The string is valid if it corresponds to an internal representation that would be created by the specified picture if the picture were used to declare a variable of type PICTURE. If the string is valid, its fixed- point decimal value is extracted and assigned to the input target. If necessary, the value is converted to the type of the input target, following the usual rules (see Section 6.4, “Data Type Conversion of Operands and Expressions”). If the string is not valid, the CONVERSION condition is signaled.

When no decimal point appears in the input stream item, the scale factor of the item is assumed to be the number of digit positions specified to the right of the V character in the picture. If no V character appears, the scale factor is zero.

Output with PUT EDIT

Used with the PUT EDIT statement, the P format item outputs a source of any computational type in the specified format. If necessary, the output source is first converted to a fixed-point decimal value, following the PL/I conversion rules. The fixed-point decimal value is then edited by the picture specified in the format item. The P format item therefore describes an output field of w characters, where w is the total number of characters in the picture, exclusive of the V character. If the output source is a pictured value, then its extracted fixed-point decimal value must be capable of being edited by the picture specified in the P format item. Otherwise, the ERROR condition is signaled.

Examples

The following tables show the relationship between the internal and external representations of numbers that are read or written with the P format item.

Input Examples

The input stream shown in this table is a field of characters beginning at the current position in the stream and continuing to the right. The # character is used to specify a space. The target type is the type of the variable to which the input value is assigned.

Table 9.13. Input with the P Format Item
Format ItemInput StreamTarget TypeTarget Value
P'$$$,$$$,$$9V.99DB'$10,987,654.00DB...DECIMAL(10,2)-10987654.00
P'$$$,$$$,$$9V.99DB'########$10.99##...DECIMAL(10,2)10.99
P'SSSSV.SSSSS'##-1.12345...DECIMAL(8,5)-1.12345
P'SSSSV.SSSSS'+100.12345...DECIMAL(8,5)100.12345
P'SSSSV.SSSSS'#100.12345...DECIMAL(8,5)[CONVERSION]
P'SSSSV.SSSSS'+1001.2345...DECIMAL(8,5)[CONVERSION]

The last two cases signal the CONVERSION condition. In the first case, the input field has a space instead of a plus symbol or minus symbol in the first position. In the second case, the input field has four digits to the left of the period, and the P format item specifies a maximum of three. The P format item in both cases uses drifting strings of S characters, and, if used to declare a picture variable, the specification could create several different character representations. However, the specification could not have created the last two input fields shown, and they are therefore invalid values.

Note that in the second line in the table, the characters "$10.99" must be surrounded with the number of spaces shown. The drifting dollar signs and the comma insertion characters always specify either digits, the characters themselves, or spaces. Similarly, the characters "DB" in the picture specification specify either these characters or the same number of spaces. If the pictured input value did not contain these spaces, it would be invalid.

Output Examples

The output source value shown in this table is either a constant or the value of a variable that is written out with the associated format item.

Table 9.14. Output with the P Format Item
Output Source ValueFormat ItemOutput Value
-12234P'$$$$$$DB'$12234DB
-12234P 'SSSSSSV.SS'-12234.00
-12.234P 'T9V.999'J2.234
-1.23456E3P '-9999V.99'-1234.56
-1.23456E3P '+ZZZ9V.99'#1234.56

9.2.4.8. PAGE Format Item

The PAGE format item is used with print files to begin a new page. See Section 9.2.6, “Terminal I/O” for more information on print files.

The form of the PAGE format item is:

PAGE

Subsequent output begins on line 1 of the next page, and the current page number for the print file is incremented by 1.

9.2.4.9. R Format Item

The R (remote) format item specifies the label of a FORMAT statement from which some or all of a format specification is obtained by a GET EDIT or PUT EDIT statement.

The form of the R format item is:

R (label)
label

The label of a FORMAT statement within the same block as the GET EDIT or PUT EDIT statement. If the item occurs in a recursive procedure, the R item and FORMAT statement must occur in the same recursion.

FORMAT Statement

The FORMAT statement describes a remote format-specification list to be used by GET EDIT or PUT EDIT statements. The FORMAT statement and remote (R) format item are useful when the same format specification is used by a large number of GET EDIT or PUT EDIT statements, or both. In this case, a change to the format specification can be made in the single FORMAT statement, rather than in each GET or PUT statement.

The form of the FORMAT statement is:

[(condition-prefix[,condition-prefix]... ):] label: FORMAT     (format-specification,...);
label

A valid PL/I label. A label is required and is specified in the GET EDIT or PUT EDIT statement that contains an R format item in its format-specification list.

condition-prefix (IBM Dialect Only)

A valid PL/I condition prefix. If you use a condition prefix on a FORMAT statement, it must be the same prefix used on the referring GET or PUT statement.

format-specification

A list of one or more format items that match corresponding input targets in a GET EDIT statement, or output sources in a PUT EDIT statement.

Although the FORMAT statement can contain another R format item, the following restrictions apply:

  • The FORMAT statement cannot designate its own label with an R format item.

  • The FORMAT statement cannot begin a chain of remote format items that leads back to the original FORMAT statement.

  • If you use a condition prefix on a remote format statement, it must be the same prefix used on the referring GET or PUT statement and the intervening format statement(s).

Examples
RFRM: PROCEDURE OPTIONS(MAIN);

       DECLARE SYSIN STREAM INPUT FILE;
       DECLARE SYSPRINT PRINT FILE;
       DECLARE SALARY PICTURE '$$$$$$$$9V.99';
       DECLARE (FIRST,MID,LAST) CHARACTER(80) VARYING;
       DECLARE 1 HIRING,
                        2 DATE CHARACTER(20) VARYING,
                        2 EXPERIENCE FIXED,
                        2 SALARY PICTURE '$$$$$$$$9V.99';
       OPEN FILE(SYSIN) TITLE('RFRM.IN');
       OPEN FILE(SYSPRINT) TITLE('RFRM.OUT');

       GET EDIT (SALARY, FIRST, MID, LAST, DATE, EXPERIENCE,
                       HIRING.SALARY)
                       (F(8,2),R(PERSONNEL_FORMAT));

       PUT SKIP LIST(TRIM(LAST)||', '||TRIM(FIRST)||
               ' '||TRIM(MID)||':  Hired '||TRIM(DATE)||' at '||HIRING.SALARY);
       PUT SKIP LIST(EXPERIENCE,' years prior experience');
       PUT SKIP LIST('Present salary: '||SALARY);

       PERSONNEL_FORMAT: FORMAT (R(NAME), A(20), SKIP, F(2), X,
                       F(8,2));
       NAME: FORMAT(3(SKIP,A(80)));

END RFRM;

Assume the file RFRM.IN contains the following data:

 25005.50
Thomasina
A.
Delacroix
6 July 1976
 2 15003.65

The following output, with spacing as shown, will be written to the print file RFRM.OUT:

Delacroix, Thomasina A.:    Hired 6 July 1976 at   $15003.65
             2   years prior experience
Present salary:    $25005.50

9.2.4.10. SKIP Format Item

The SKIP format item sets a stream file to a new position relative to the current line. It is used with input and output files.

The form of the SKIP format item is:

SKIP [(w)]
w

An integer, or an expression, giving the number of lines to be skipped; the expression must not convert to a negative integer and must be greater than zero, except for print files. If w is omitted, a value of 1 is assumed.

If w is 1 or is omitted, the file is positioned at the beginning of the next line. If w is greater than 1, w-1 lines are skipped on input, but the ENDFILE condition is signaled if the end of the file is encountered first. On output, w-1 blank lines are inserted. In both cases, the new position is the beginning of (current line)+w.

Use with Print Files

If w is zero, the file is repositioned at the beginning of the current line, allowing overprinting of the line. If w is greater than zero, and either the current line exceeds the page size or the page size is greater than or equal to the current line plus w, then w-1 blank lines are inserted. Otherwise, the remainder of the page (the portion between the current line and the page size) is filled with blank lines, and the ENDPAGE condition is signaled.

9.2.4.11. TAB Format Item

The TAB format item sets a print file to a specified tab stop. It is used only for output to print files. Within a line, tab stops always occur every eight columns, starting at column 1. The form of the TAB format item is:

TAB [(w)]
w

An integer, or an expression, that identifies the wth tab stop from the current position; w must not be negative. If w equals zero, no operation is performed. If w is omitted, a value of 1 is assumed.

When the TAB format item is executed, the current column (cc) is determined. If the current position is the beginning of a line, page, or file, then cc is one. Otherwise, cc is the column in the current line at which the next output character would appear.

For example, if seven characters have already been written on a line, then the cc is column 8; this is where the next output would occur. The file is then repositioned in one of the following ways:

  • If there are at least w tab stops between (cc+1) and the end of the line, then the file is moved to the wth tab stop from the current column, and the intervening positions are filled with spaces. The end of the line is at one column after the current line size, which is either the default value or the specific value that you have established for the file. See Section 9.1, “Opening and Closing Files” for LINESIZE option.

  • If there are fewer than w tab stops on the remainder of the current line, the file is skipped to the beginning of the next line and positioned at the first tab stop (column 1). If, before the skip operation, the current line was the last line on the page, the ENDPAGE condition is signaled, and the current line becomes (page size)+1. The page size is either the default value or the specific value that you have established for the file. See Section 9.1, “Opening and Closing Files” for PAGESIZE option.

Examples
TAB: PROCEDURE OPTIONS(MAIN);

       DECLARE OUT STREAM OUTPUT PRINT FILE;

       OPEN FILE(OUT) LINESIZE(60);
       PUT FILE(OUT) SKIP
               EDIT('123456789012345678901234567890') (A);

       PUT FILE(OUT) SKIP EDIT('COL1','?') (A,TAB(2),A);
       PUT FILE(OUT) EDIT('!') (TAB(20),A);
       PUT FILE(OUT) SKIP EDIT('*') (TAB(1),A);
       PUT FILE(OUT) EDIT('abcdefg') (A); /* cc now = 17 */
       PUT FILE(OUT) EDIT('&') (TAB(6),A);
END TAB;

The program TAB writes the following output to the print file OUT.DAT:

123456789012345678901234567890
COL1            ?
!
        *abcdefg
&

The question mark appears in column 17, which is the second tab stop following the string `COL1'. The exclamation point appears in column 1 of the next line because there are fewer than 20 tab stops on the remainder of the line. In the third PUT EDIT statement, the SKIP option first resets the current column to zero. When the TAB format item is executed, it must position the file to the first tab stop that is between column 1 (cc+1) and the end of the line; therefore, the file is positioned, and the asterisk appears, in column 9. Similarly, the fourth statement writes out the string `abcdefg', after which the current column is 17, a tab stop. Because the line size has been established as 60, there are only five tab stops between cc+1 and the end of the line: 25, 33, 41, 49, and 57. Therefore, the format item TAB(6) in the last PUT EDIT statement causes a skip to the next line, and the ampersand appears in column 1.

9.2.4.12. X Format Item

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:

X [(w)]
w

An 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, “Opening and Closing Files” 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.

Examples
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(80)) 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 `Line >'. Assume that the interaction is as follows:

Line> beautiful losers Return

The following output will be written to OUTFILE.DAT:

beautiful  -FIRST WORD TYPED

The X format item has correctly inserted two spaces between `beautiful' and `-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:

Line> ABCDEFGHIJKLMNOPQRSTUVWXYZ Return

The following output will be written to OUTFILE2.DAT:

KLMNOPQRSTUVWXYZ

The first 10 letters (A to J) have been ignored on input.

9.2.4.13. 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:

{ format-item                             }
{ iteration-factor format-item            }
{ iteration-factor (format-item, ...)     }

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));

The preceding statement specifies a 5-character field containing decimal digits, two of which are fractional. Used by itself as a format specification, this item specifies one such field. To specify two such fields, precede the item with the iteration factor 2:

PUT EDIT (A,B) (2F(5,2));

Or:

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:

F(5,2),F(7,2),E(8),F(7,2),E(8),F(5,2),F(7,2),E(8),F(7,2),E(8)

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 List

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.

  • A GET EDIT or PUT EDIT statement must include one and only one format- specification list and also one and only one list of input targets or output sources. The input-target or output-source list must immediately follow the keyword EDIT and must be immediately followed by the format-specification list.

  • The same set of data format items is used for input and output. The F and E format items are used for I/O in fixed-point and floating-point formats, respectively. The A and B format items are used for I/O in character-string and bit-string formats, respectively. The P format item is used for both input and output of data, with the format specified by a picture contained in the format item.

  • Of the control format items, only X can be used when the input or output stream is a character string.

  • Unlike the statement options PAGE, LINE, and SKIP, the format items PAGE, LINE, and SKIP are executed in the order in which they occur.

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-specification

One 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-target

One 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-source

One 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.

Examples

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 Variables

The 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));

The preceding 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));

The preceding 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));

The preceding 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) );

The preceding 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) );

The preceding statement performs the same operation as in the previous example, but acquires the 20-character string from the next line.

Aggregates

The following examples have input targets that are references to array and structure variables:

GET EDIT (A) ( 2( A(12),A(14) ), A(20) );

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,B) ( 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 (NAME) (SKIP,A(20),SKIP,A(80));

NAME is a structure declared as:

DECLARE 1 NAME,
                       2 FIRST CHARACTER(20) VARYING,
                       2 LAST CHARACTER(80) VARYING;

The following 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.

GET EDIT (A,B) ( 2( A(12),A(14) ), SKIP, A(20) );

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.

DO Specifications

The 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.

Example 1:
GET EDIT ( (B(I) DO I=10 TO 4 BY -2) , B(1) )
       ( 2( A(12),A(14) ), A(20) );

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. The preceding 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. It then executes A(20) and assigns the result to B(1).

Example 2:
GET EDIT ( ( (A(I,J) DO J=1 TO 10) DO I=1 TO 20) )
       (F(5),F(6));

In the preceding statement, 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) (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 to a DO construct in an input-target list, however, nested DO groups are much less efficient in execution speed. In addition, some stream I/O statements may have different effects when specified in nested DO-groups as opposed to being specified with the DO construct in the input-target list. For example:

GET SKIP EDIT(input-target, ...) (format-specification, ...);

If you use this syntax in a pair of nested DO groups, as shown previously, the SKIP option is executed on each iteration of the innermost DO group. If you specify the DO construct in the input-target list, the SKIP option is executed only once, before any other input processing is performed.

Example 3:
GET EDIT ( ( CURRENT->PERSON.NAME
       DO CURRENT = FIRST
       REPEAT CURRENT->PERSON.NEXT
       WHILE (CURRENT ^= NULL) ) )
               (A(80));

CURRENT and FIRST are pointers, and PERSON is a based structure declared as:

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 reads 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 use 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.

9.2.5. Processing and Positioning of Character Strings

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:

  • Input can begin either at the beginning of the string or at a specified character position. The ERROR condition is signaled if the end of the string is encountered. Only the X format item is used for positioning.

  • The first output by a PUT statement always occurs at the beginning of the string, and subsequent output by the same statement follows the previous output. The ERROR condition is signaled if the maximum length of the string is exceeded. Only the X format item is used for positioning.

9.2.6. Terminal I/O

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.

The file symbols "SYSPRINT", "SYSIN", and "SYSOUT" are always case insensitive regardless of the specified compiler option. In other words, whether you specify "sysprint", "Sysprint", or "SYSPRINT", you will always refer to the pre-declared PL/I files.

The file symbol "SYSOUT" is supported in the dec and ansi dialects; the file symbols "SYSPRINT" and "SYSIN" are supported in dec, ansi, and ibm dialects.

For further information, see the Endless PL/I for POSIX Systems User's Manual.

9.2.6.1. 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);

The preceding statement gets three character strings from the terminal. The strings are converted automatically to the target data types and assigned to the scalar variable SALARY, element 42 of the array CONTRIBUTION, and member DEDUCTION of the structure PAYROLL. There are several sequences with which the user can type the needed values, including the following:

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 (See Section 9.2.2, “Input by the GET Statement”).

9.2.6.2. Simple Output to a Terminal

You can send data to a terminal with the PUT LIST statement. A simple form of PUT LIST is as:

PUT LIST (output-source, ...);

The output sources in simple cases are expressions, including variable references. The PUT LIST statement converts the results of the expressions to the appropriate character representations and sends the character strings to the terminal. For instance:

PUT LIST (A,B,C);

This statement converts the values of the variables A, B, and C to character strings and sends the results to the terminal. In this simple case, the displayed strings are separated by tabs.

The file SYSPRINT, used as the default output stream by PUT LIST, is a print file, and the terminal has the characteristics of print files.

9.2.6.3. Print File

A print file is a stream output file that is intended for output on a terminal, line printer, or other output device. You can declare any stream output file to be a print file by using the PRINT attribute. The default stream output file, SYSPRINT, is a print file.

The following list describes the special features of print files, as opposed to ordinary stream output files:

  • Character strings are not enclosed in apostrophes on list-directed output.

  • List-directed output data items are separated by tabs instead of spaces. Tab stops occur at 8-column increments beginning with column 1. With the PUT EDIT statement and the TAB format item, you can begin output at a specified tab stop.

  • An internal record is kept of the current line in a print file. The LINENO built-in function returns the current line number for a specified file. This function allows you to keep track of the number of lines being written to a file and to decide where page advances should occur.

  • Print files are divided into both lines and pages. An internal record is kept of the number of lines per page. You can specify a page size when the print file is created (see Section 9.1, “Opening and Closing Files” for PAGESIZE option).

  • During output of data to a print file, the ENDPAGE condition is signaled when the output exceeds the page size.

  • New pages are started by the PUT PAGE statement, the PAGE format item, and certain other format items. Each of these operations increments the current page number by 1. The PAGENO built-in function returns the current page number from a print file. This function allows you to keep track of the number of pages being written to a file. You can set the current page number to a specific value by assigning the value to the PAGENO pseudovariable.

  • If the print file is a terminal, the output is written to the terminal at the conclusion of each PUT statement.

  • A print file is created with PRN-format carriage control. PRN format is efficient for both terminals and line printers because blank lines do not require individual records. (PRN format is discussed in the OpenVMS Record Management Services Reference Manual.)

  • Print files usually cannot be read properly with GET LIST or GET EDIT.

Examples
SIMPLE_INPUT: PROCEDURE OPTIONS (MAIN);
       /* Simple input from user's terminal */
       DECLARE BADGE_NUMBER FIXED DECIMAL (5),
                       SOCIAL_SECURITY_NUMBER CHARACTER(11);

       GET LIST (BADGE_NUMBER,SOCIAL_SECURITY_NUMBER);
       PUT LIST (BADGE_NUMBER,SOCIAL_SECURITY_NUMBER);

END SIMPLE_INPUT;

PL/I does not display a prompt character on the terminal when a program executes a GET or READ statement. Consequently, it is difficult to tell that a program is trying to read data unless the program executes an output statement containing a prompting message. The program SIMPLE_INPUT would be easier to use if the following statement appeared immediately before GET LIST:

PUT SKIP LIST('Enter badge number, social security number:');

The cursor remains on the same line after the prompt is displayed, so the input can be entered on the same line. The completed line might be:

Enter badge number, social security number: 7,116-40-0482 Return

The GET statement also has a PROMPT statement option that displays a prompt on the user's terminal. See the Endless PL/I for POSIX Systems User's Manual.

TIN: PROCEDURE OPTIONS(MAIN);

       DECLARE STRING CHAR(10) VARYING,
               I FIXED BINARY STATIC INITIAL(0),
               A FLOAT BINARY;
       DECLARE EOF BIT STATIC INITIAL('0'B);

       ON ENDFILE(SYSIN) EOF = '1'B;
       PUT SKIP LIST('Enter string, integer, float>');
       GET LIST(STRING,I,A);
       DO WHILE(^EOF); /* stop when CTRL/D is typed */
               PUT SKIP LIST(STRING,I,A);
               PUT SKIP LIST('Enter string, integer, float>');
               GET LIST(STRING,I,A);
       END;

END TIN;

Here, the user is prompted to enter three values from the default file SYSIN. The three values are immediately written out to the default file SYSPRINT. This sequence continues until the user answers the prompt with a Ctrl/D, which signals the ENDFILE condition for SYSIN; the program then terminates. The following is a sample dialog with the program:

$ RUN TIN Return
Enter string, integer, float>  JONES,27,3.75 Return
JONES  27      3.7500000E+00
Enter string, integer, float>  JONES 27 3.75 Return
JONES  27      3.7500000E+00
Enter string, integer, float> JONES Return
27KEY(Return)
3.75;KEY(Return)
JONES  27      3.7500000E+00
Enter string, integer, float>  DOOLEY Return
KEY(Return)
4E-6;KEY(Return)
DOOLEY 0       4.0000000E-06
Enter string, integer, float> Ctrl+Z
$

Notice that input fields are separated by commas, spaces, or the RETURN key. Notice also that entering a blank line after `DOOLEY' causes the program to set the value of I to zero.

Other Topics

The following topics are of interest in terminal I/O applications:

9.3. Record I/O

Record I/O is performed by the READ, WRITE, DELETE, and REWRITE statements. In addition, the LOCATE statement is accepted in the IBM dialect.

In record I/O, each I/O statement processes an entire record. (In stream I/O, more than one line or record can be processed by a single statement.) Table 9.15, “Attributes and Access Modes for Record Files” summarizes the file description attributes that apply to record I/O.

Table 9.15. Attributes and Access Modes for Record Files
Attributes SpecifiedAttributes ImpliedValid Devices and File OrganizationsUsage
SEQUENTIAL OUTPUTRECORDAny output device or fileRecords can be added to the end of the file with WRITE statements. Each WRITE statement adds a single record to the file.
SEQUENTIAL OUTPUT BUFFEREDRECORDAny output device or fileSimilar to SEQUENTIAL OUTPUT. In addition, the LOCATE statement can be used. (ibm dialect only)
SEQUENTIAL INPUTRECORDAny input device or fileRecords in the file are read with READ statements. Each statement reads a single record.
SEQUENTIAL UPDATERECORDRelative, streamREAD statements read a file's records in order. PL/I maintains the current record, which is the record just read. This record can be replaced in a REWRITE statement. In a relative file, the current record can also be deleted with a DELETE statement. Each statement processes a single record.
DIRECT OUTPUTKEYED RECORDRelative, streamWRITE statements insert records into the file at positions specified by keys. Each statement inserts a single record.
DIRECT INPUTKEYED RECORDRelative, streamREAD statements specify records to be read randomly by key. Each statement reads a single record.
DIRECT UPDATEKEYED RECORDRelative, streamREAD, WRITE, and REWRITE statements specify records randomly by key. In a relative file, records can also be deleted by key.
KEYED SEQUENTIAL OUTPUTRECORDRelative, streamWRITE statements insert records into the file at positions specified by keys. Each statement inserts a single record. This mode is identical to DIRECT OUTPUT.
KEYED SEQUENTIAL INPUTRECORDRelative, streamREAD statements access records in the file randomly by key or sequentially.
KEYED SEQUENTIAL UPDATERECORDRelative, streamAny record I/O operation is allowed except a WRITE statement that does not specify a key or a DELETE statement for a sequential disk file with fixed- length records.

9.3.1. READ Statement

The READ statement reads a record from a file, either the next record or a record specified by the KEY option. The file must have either the INPUT or the UPDATE attribute.

The format of the READ statement is:

READ FILE (file-reference)
{ INTO(variable-reference) }
{ SET(pointer-variable)    }
[ KEY(expression)           ]
[ KEYTO(variable-reference) ]
[OPTIONS(option, ...)]
[IGNORE(expression)] ;
FILE(file-reference)

The file from which the record is to be read. If the file is not currently open, PL/I opens the file with the implied attributes RECORD and INPUT. The implied attributes are merged with the attributes specified in the file's declaration.

INTO (variable-reference)

An option that specifies that the contents of the record are to be assigned to the specified variable. The variable must be an addressable variable. The INTO and SET options are mutually exclusive.

  • If the variable has the VARYING attribute and the file does not have the attribute ENVIRONMENT(SCALARVARYING), the entire record is treated as a string value and assigned to the variable. If the record is larger than the variable, it is truncated and the ERROR condition is signaled.

  • If the variable has the AREA attribute and the file does not have the attribute ENVIRONMENT(SCALARVARYING), the entire record is treated as an area value and assigned to the variable. If the extent of the area in the record is larger than the variable, the AREA condition is signaled and the target area is unmodified.

  • For any other type of variable, the record is copied into the variable's storage. If the record is not exactly the same size as the target variable, as much of the record as will fit is copied into the variable and the ERROR condition is signaled.

SET (pointer-variable)

An option that specifies that the record should be read into a buffer allocated by PL/I and that the specified pointer variable should be assigned the value of the location of the buffer in storage. The SET and INTO options are mutually exclusive.

This buffer remains allocated until the next operation on the file but no longer. Therefore, do not use either the pointer value or the buffer after the next operation on the file. The only valid use of the buffer during a subsequent I/O operation is in a REWRITE statement. In this case, you can rewrite the record from the buffer before the buffer is deallocated.

KEY (expression)

An option that specifies that the record to be read is to be located using the key specified by the expression. The file must have the KEYED attribute. The KEY and KEYTO options are mutually exclusive.

For a relative file or a sequential disk file with fixed-length records, the key is a fixed binary value indicating the relative record number of the record to be read.

The value of the specified expression is converted to the data type of the key. If no record with the specified key exists in the file, or if the value specified is not valid for conversion to the data type of the key, the KEY condition is signaled.

KEYTO (variable-reference)

An option that specifies that the key of the record being read is to be assigned to the designated variable. The value of the key is converted from the data type implied by the file's organization to the data type of the variable. The variable must have a computational data type but cannot be an unaligned bit string or an aggregate consisting entirely of unaligned bit strings. The KEYTO and KEY options are mutually exclusive.

KEYTO is specified only for a file that has both the KEYED and SEQUENTIAL attributes.

OPTIONS (option, ...) (dec and ansi dialects only)

An option that specifies one or more of the following READ statement options, separated by commas:

RECORD_ID (variable-reference)

RECORD_ID_TO (variable-reference)

All these options except remain in effect for the current statement only. These options are described fully in the Endless PL/I for POSIX Systems User's Manual.

IGNORE (expression) (IBM Dialect Only)

An option that specifies the number of records to skip on the next READ of a SEQUENTIAL INPUT or SEQUENTIAL UPDATE file. The expression must evaluate to an integer value n. If the expression evaluates to one (1) or more, the next READ statement for the file will retrieve (n+1)th record. If the expression is less than one (1), this READ statement has no effect. For example, the following expression specifies that the next five records in the PERSONNEL file should be ignored:

READ FILE (PERSONNEL) IGNORE(5);

9.3.1.1. File Positioning Following a READ Statement

If the file is accessed sequentially, the READ statement reads the next record in the file. If the next-record position is at the end-of-file, the ENDFILE condition is signaled.

After a successful read operation, the current record position in the file denotes the record that was just read. The next-record position denotes the following record or, if there is no following record, the end-of-file.

If any error other than an incorrect record size occurs, the current record becomes undefined and the next record is the same as it was before the read operation was attempted.

Examples
COPY: PROCEDURE;
       DECLARE INREC CHARACTER(80) VARYING,
                       ENDED BIT(1) STATIC INIT('0'B),
                       (INFILE,OUTFILE) FILE;

       OPEN FILE (INFILE) RECORD INPUT
                       TITLE('RECFILE.DAT');
       OPEN FILE (OUTFILE) RECORD OUTPUT
                       TITLE('COPYFILE.DAT');
       ON ENDFILE(INFILE) ENDED = '1'B;

       READ FILE(INFILE) INTO (INREC);
       DO WHILE (^ENDED);
                       WRITE FILE (OUTFILE) FROM (INREC);
                       READ FILE (INFILE) INTO (INREC);
       END;
       CLOSE FILE(INFILE);
       CLOSE FILE(OUTFILE);
       RETURN;
END;

The program COPY reads a file with variable-length records into a character string with the VARYING attribute and writes the records to a new output file.

It uses a DO-group to read the records in the file sequentially until the end-of-file is reached. It uses the ON statement to establish the action to be taken when the end-of-file occurs: it sets the bit ENDED to '1'B so that the DO-group will not be executed again.

The VARYING character-string variable INREC has a maximum length of 80 characters. If any record in the file is more than 80 characters, the ERROR condition is signaled. If no ERROR ON-unit exists, the program exits.

PRINT_DATA: PROCEDURE OPTIONS(MAIN);
       DECLARE 1 EMPLOYEE BASED (EP),
                               2 NAME,
                                       3 LAST CHAR(30),
                                       3 FIRST CHAR(20),
                                       3 MIDDLE_INIT CHAR(1),
                               2 DEPARTMENT CHAR(4),
                               2 SALARY FIXED DECIMAL (6,2),
                       EP POINTER,
                       EMP_FILE FILE;

       DECLARE EOF BIT(1) STATIC INIT('0'B),
                       NUMBER FIXED BIN(31);

       ON ENDFILE(EMP_FILE) EOF = '1'B;
       OPEN FILE(EMP_FILE) INPUT SEQUENTIAL KEYED;
       READ FILE(EMP_FILE) SET(EP) KEYTO(NUMBER);
       DO WHILE (^EOF);
               PUT SKIP LIST('EMPLOYEE',NUMBER,
                       EMPLOYEE.NAME.FIRST,EMPLOYEE.NAME.LAST,
                       EMPLOYEE.NAME.MIDDLE_INIT);
               READ FILE(EMP_FILE) SET(EP) KEYTO(NUMBER);
               END;
       CLOSE FILE(EMP_FILE);

END;

The PRINT_DATA program accesses a relative file sequentially with READ statements and obtains the key value of each record, that is, the relative record number. The records in the file EMP_FILE are arranged according to employee numbers. Each employee number corresponds to a relative record number in the file. The READ statements read records into the based structure EMPLOYEE and set the pointer EP to the location of the allocated buffer. The READ statements specify the KEYTO option to obtain the record number of each record. The procedure prints the employee numbers and names. When the last record has been read, the program closes the input file and exits.

9.3.2. WRITE Statement

The WRITE statement adds a record to a file, either at the end of a file that has the SEQUENTIAL and OUTPUT attributes, or in a specified key position in a file that has the KEYED and OUTPUT attributes or the KEYED and UPDATE attributes. The format of the WRITE statement is:

WRITE FILE(file-reference) FROM (variable-reference)
       [ KEYFROM (expression) ]
       [ OPTIONS (option, ...) ];
FILE (file-reference)

A reference to the file to which the record is to be written. If the file is not currently open, the WRITE statement opens the file with the implied attributes RECORD, OUTPUT, and SEQUENTIAL; these attributes are merged with the attributes specified in the file's declaration.

FROM (variable-reference)

A reference to the variable containing data for the output record. The variable must be addressable.

If the variable has the VARYING or the AREA attribute and the file does not have the attribute ENVIRONMENT(SCALARVARYING), the WRITE statement writes only the current value of the varying string or the area into the specified record. In all other cases, the WRITE statement writes the entire storage of the variable. If the contents of the variable do not fit the specified record size, the WRITE statement outputs as much of the variable as will fit, and the ERROR condition is signaled.

KEYFROM (expression)

An option specifying that the record to be written is to be positioned in the file according to the key specified by the expression. The file must have the KEYED attribute.

In a relative file or a sequential disk file with fixed-length records, the key value is a fixed binary value indicating the relative record number of the record to be written.

The value of the specified expression is converted to the data type of the key. If the specified key value cannot be converted to the data type of the key, the KEY condition is signaled.

OPTIONS (option) (dec and ansi dialect only)

An option specifying the WRITE statement option RECORD_ID_TO. The format of this option is:

RECORD_ID_TO (variable-reference)

This option is described fully in the Endless PL/I for POSIX Systems User's Manual.

9.3.2.1. File Positioning Following a WRITE Statement

If the file has the UPDATE attribute, the current record is set to designate the record just written, and the next record is set to designate the record following the record just written. If there is no such record following the record just written, the next record is set to the end-of-file.

Examples
TRUNC: PROCEDURE;
       DECLARE INREC CHARACTER(80) VARYING,
                       OUTREC CHARACTER(80),
                       ENDED BIT(1) STATIC INIT('0'B),
                       (INFILE,OUTFILE) FILE;

       OPEN FILE (INFILE) RECORD INPUT
               TITLE('RECFILE.DAT');
       OPEN FILE (OUTFILE) RECORD OUTPUT
               TITLE('TRUNCFILE.DAT')
               ENVIRONMENT(FIXED_LENGTH_RECORDS,
               MAXIMUM_RECORD_SIZE(80));

       ON ENDFILE(INFILE) ENDED = '1'B;
       READ FILE(INFILE) INTO (INREC);
       DO WHILE (^ENDED);
               OUTREC = INREC;
               WRITE FILE (OUTFILE) FROM (OUTREC);
               READ FILE (INFILE) INTO (INREC);
       END;

       CLOSE FILE(INFILE);
       CLOSE FILE(OUTFILE);
       RETURN;
END;

The TRUNC procedure reads a file with variable-length records into a character string with the VARYING attribute and creates a sequential output file in which each record has a fixed length of 80 characters.

The ENVIRONMENT attribute for the file OUTFILE specifies the record format and length of each fixed-length record.

When records are written to a file with fixed-length records, the variable specified in the FROM option must have the same length as the records in the target output file. Otherwise, the ERROR condition is signaled. Thus, in this example, each record read from the input file is copied into a fixed-length character-string variable for output.

The TRUNC procedure creates a new version of the file TRUNCFILE.DAT every time it executes.

ADD_EMPLOYEE: PROCEDURE;

       DECLARE 1 EMPLOYEE,
                               2 NAME,
                                       3 LAST CHAR(30),
                                       3 FIRST CHAR(20),
                                       3 MIDDLE_INIT CHAR(1),
                               2 DEPARTMENT CHAR(4),
                               2 SALARY FIXED DECIMAL (6,2),
                       EMP_FILE FILE;

       DECLARE MORE_INPUT BIT(1) STATIC INIT('1'B),
                       NUMBER FIXED DECIMAL (5,0);

       OPEN FILE(EMP_FILE) DIRECT UPDATE;

       DO WHILE (MORE_INPUT);
               PUT SKIP LIST('Employee Number');
               GET LIST (NUMBER);
               PUT SKIP LIST ('Name (Last, First, Middle Initial)');
               GET LIST (EMPLOYEE.NAME.LAST,EMPLOYEE.NAME.FIRST,
                       EMPLOYEE.NAME.MIDDLE_INIT);

               PUT SKIP LIST('Department');
               GET LIST (EMPLOYEE.DEPARTMENT);

               PUT SKIP LIST('Starting salary');
               GET LIST(EMPLOYEE.SALARY);

               WRITE FILE (EMP_FILE)
                       FROM (EMPLOYEE) KEYFROM(NUMBER);

               PUT SKIP LIST('More?');
               GET LIST(MORE_INPUT);
       END;
       CLOSE FILE(EMP_FILE);
       RETURN;
END;

The ADD_EMPLOYEE procedure adds records to the existing relative file EMP_FILE. The file is organized by employee numbers, and each record occupies the relative record number in the file that corresponds to the employee number.

The file is opened with the DIRECT and UPDATE attributes, because records to be written will be chosen by key number. Within the DO- group, the program prompts for data for each new record that will be written to the file. After the data is input, the WRITE statement specifies the KEYFROM option to designate the relative record number. The number itself is not a part of the record but will be used to retrieve the record when the file is accessed for keyed input.

9.3.3. DELETE Statement

The DELETE statement deletes a record from a file. This record can be the current record, the record specified by the KEY option, or the record specified by the RECORD_ID option. The file must have the UPDATE attribute.

The format of the DELETE statement is:

DELETE FILE(file-reference) [KEY (expression)] [OPTIONS(option, ...)];
FILE(file-reference)

A reference to the file from which the specified record is to be deleted. If the file is not currently opened, PL/I opens the file with the implied attributes RECORD and UPDATE; these attributes are merged with the attributes specified in the file's declaration.

KEY (expression)

An option specifying that the record to be deleted will be located by the key specified in the expression. The file must have the KEYED attribute.

In a relative file, the key is a fixed binary value indicating the relative record number of the record to be deleted.

The value of the specified expression is converted to the data type of the key. If no record with the specified key exists in the file, or if the value specified is not valid for conversion to the data type of the key, the KEY condition is signaled.

OPTIONS(option, ...) (dec and ansi dialects only)

An option giving one or more of the following DELETE statement options:

FAST_DELETE

RECORD_ID (reference)

Multiple options must be separated by commas.

All these options remain in effect for the current statement only.

These options are described fully in the Endless PL/I for POSIX Systems User's Manual.

9.3.3.1. File Positioning Following a DELETE Statement

The next record is set to denote the record following the deleted record. The current record is undefined.

9.3.4. REWRITE Statement

The REWRITE statement replaces a record in a file. The record is either the current record or the record specified by the KEY option. The file must have the UPDATE attribute. The format of the REWRITE statement is:

REWRITE FILE (file-reference)
       [ FROM (variable-reference) [ KEY (expression) ]]
       [ OPTIONS (option, ...) ];
FILE(file-reference)

The file that contains the record to be replaced. If the file is not open, it is opened with the implied attributes RECORD and UPDATE; these attributes are merged with the attributes specified in the file's declaration.

FROM (variable-reference)

An option giving the variable that contains the data needed to rewrite the record. The variable must be an addressable variable.

If the FROM option is not specified, there must be a currently allocated buffer from an immediately preceding READ statement that specifies the SET option, and this file must have the SEQUENTIAL attribute. In this case, the record is rewritten from the buffer containing the record that was read. Note that if the file organization is sequential, the record being rewritten must be the same length as the one read.

If the variable has the VARYING or the AREA attribute and the file does not have the attribute ENVIRONMENT(SCALARVARYING), the REWRITE statement writes only the current value of the varying string or area into the specified record. In all other cases, the REWRITE statement writes the variable's entire storage.

KEY (expression)

An option specifying that the record to be rewritten is to be located using the key specified by expression. The file must have the KEYED attribute. The expression must have a computational data type. The FROM option must be specified.

In a relative file or a sequential disk file with fixed-length records, the key is a fixed binary value indicating the relative record number of the record to be rewritten.

The value of the specified expression is converted to the data type of the key. If no record with the specified key exists, or if the value specified is not valid for conversion to the data type of the key, the KEY condition is signaled.

OPTIONS (option, ...)

An option giving one or more of the following REWRITE statement options. Multiple options must be separated by commas.

FIXED_CONTROL_FROM (variable-reference)

INDEX_NUMBER (expression)

MATCH_GREATER

MATCH_GREATER_EQUAL

MATCH_NEXT

MATCH_NEXT_EQUAL

RECORD_ID (expression)

RECORD_ID_TO (variable-reference)

All these options except INDEX_NUMBER remain in effect for the current statement only. These options are described fully in the Endless PL/I for POSIX Systems User's Manual.

9.3.4.1. File Positioning Following a REWRITE Statement

The next record position is set to denote the record immediately following the record that was rewritten or, if there is no following record, the end-of-file.

The current record is set to designate the record just rewritten.

Examples

The procedure NEW_SALARY, below, updates the salary field in a relative file containing employee records. The procedure receives two input parameters: the employee number and the new salary. The employee number is the key value for the records in the relative file.

NEW_SALARY: PROCEDURE (EMPLOYEE_NUMBER,PAY);

       DECLARE EMPLOYEE_NUMBER FIXED DECIMAL(5,0),
               PAY FIXED DECIMAL (6,2);



       DECLARE 1 EMPLOYEE,
                               2 NAME,
                                       3 LAST CHAR(30),
                                       3 FIRST CHAR(20),
                                       3 MIDDLE_INIT CHAR(1),
                               2 DEPARTMENT CHAR(4),
                               2 SALARY FIXED DECIMAL (6,2),
                       EMP_FILE FILE;

       OPEN FILE(EMP_FILE) DIRECT UPDATE;
       READ FILE(EMP_FILE) INTO(EMPLOYEE)
                       KEY (EMPLOYEE_NUMBER);
       EMPLOYEE.SALARY = PAY;
       REWRITE FILE(EMP_FILE) FROM(EMPLOYEE)
                       KEY(EMPLOYEE_NUMBER);
       CLOSE FILE(EMP_FILE);
       RETURN;
END;

In this example, the KEY option is specified in the READ statement that obtains the record of interest and in the REWRITE statement that replaces the record, with its new information, in the file. The FROM and KEY options must both be specified on the REWRITE statement.

The sample program CHANGE_HEADER, below, changes the contents of the first record in the sequentially organized file TITLE_PAGE. The file consists of 80-byte, fixed-length records.

CHANGE_HEADER: PROCEDURE OPTIONS(MAIN);

       DECLARE TITLE_PAGE FILE SEQUENTIAL UPDATE,
                       INREC CHARACTER(80) BASED(P),
                       P POINTER;

       OPEN FILE(TITLE_PAGE);
       READ FILE(TITLE_PAGE) SET(P);

       INREC = 'Summary of Courses for Fall 1980';
       REWRITE FILE(TITLE_PAGE);
       CLOSE FILE(TITLE_PAGE);
       RETURN;
END;

In this example, the READ statement specifies the SET option. The input record is read into a buffer, INREC, that is a based character-string variable. The assignment statement modifies the buffer, and the REWRITE statement rewrites the record. Because the REWRITE statement does not specify a FROM option, PL/I uses the contents of the buffer to rewrite the current record in the file (that is, the record that was just read).

9.3.5. LOCATE Statement (IBM Dialect Only)

Use the LOCATE statement for output to a sequential file from a buffer. The LOCATE statement allocates storage in an output buffer for a based variable. It sets a pointer to the storage location in the buffer.

After executing the LOCATE statement, you can assign values directly to the output buffer by referencing based variables. Use the pointer variable set by the LOCATE statement to qualify by the based variables.

The next LOCATE, WRITE, or CLOSE statement for the referenced file transmits the data in the output buffer to the file.

The LOCATE statement can result in faster execution if the file contains large records and each record is referenced once or very few times. Although the indirect addressing technique incurs a small amount of overhead, there is less data movement, and less storage may be required.

To further optimize performance when writing large records, build the record in local variables in your program. Then assign the entire record to the output buffer using the pointer variable set by the LOCATE statement.

The format of the LOCATE statement is:

LOCATE based-variable FILE (file-reference)
       [ SET (pointer-reference) ]
       [ KEYFROM (expression) ];
based-variable

An unsubscripted level-1 based variable.

FILE(file-reference)

The output file to which buffers will be written. If the file is not open, it is opened with the implied attributes RECORD and OUTPUT; these attributes are merged with the attributes specified in the file declaration.

SET (pointer-variable)

Specifies a pointer variable to contain the value of the location of the record in the allocated storage buffer. If you do not specify the SET option, the LOCATE sets the pointer declared with the record variable.

If the record contains an element that is a varying-length string variable, you must specify the ENVIRONMENT(SCALARVARYING) option for the file.

The buffer remains allocated until the next LOCATE, WRITE or CLOSE operation on the file but no longer. Therefore, do not use either the pointer value or the buffer after the next LOCATE, WRITE or CLOSE operation on the file. The only valid use of the buffer during a subsequent I/O operation is in a REWRITE statement. In this case, you can rewrite the record from the buffer before the buffer is deallocated.

KEYFROM (expression)

Specifies that, when the record in the storage buffer is written to the file, it will be positioned in the file according to the key specified by the expression. The file must have the KEYED attribute.

In a sequential file with fixed-length records, the key value is a fixed binary value indicating the relative record number of the record to be located.

The value of the specified expression is converted to the data type of the key. If the specified key value cannot be converted to the data type of the key, the KEY condition is signaled.

9.3.5.1. File Positioning Following a LOCATE Statement

The next record position is set to the end-of-file. The current record is set to designate the record just written.

9.3.6. Position Information for a Record File

When a record file is open, PL/I maintains the following position information:

  • The next record, for files with the SEQUENTIAL INPUT or SEQUENTIAL UPDATE attributes. The next record designates the record that will be accessed by a READ statement that does not specify the KEY option. The next record may contain the end-of-file.

  • The current record, for a file with the UPDATE attribute. The current record designates either of the following:

    • The record that will be modified by a REWRITE statement that does not specify the KEY option

    • The record that will be deleted by a DELETE statement that does not specify the KEY option

    The value of the current record may be undefined.

When a file is opened the current record is undefined and the next record designates the first record in the file or, if the file is empty, the end-of-file.

After a sequential read operation, the current record designates the record just read. The next record indicates the following record or, if there are no more records, the end-of-file.

After a keyed I/O statement, that is, an I/O statement that specifies the KEY or KEYFROM option, the current record and next record are set as described in Table 9.16, “Position Information for a Record File”. (X is the record specified by key and X+1 is the next record or, if there are no more records, the end-of-file.)

Table 9.16. Position Information for a Record File
StatementCurrent RecordNext Record
READXX+1
WRITEXX+1
REWRITEXX+1
DELETEundefinedX+1