Structure Input and Output
Structures are read and written using the formatted and unformatted I/O procedures READ, READF, PRINT, PRINTF, READU, and WRITEU. Structures and arrays of structures are transferred in much the same way as simple data types, with each element of the structure transferred in order.
Formatted Input and Output with Structures
Writing a structure with PRINT, or PRINTF and the default format, outputs the contents of each element using the default format for the appropriate data type. The entire structure is enclosed in braces: “{ }”. Each array begins a new line.
For example, printing the variable STAR, as defined in the first example in this chapter, results in the output:
{ SIRIUS 30.0000 40.0000
0.00000 1.00000 2.00000 3.00000
4.00000 5.00000 6.00000 7.00000
8.00000 9.00000 10.0000 11.0000
}
When reading a structure with READ, or READF and the default format, white space should separate each element. Reading string elements causes the remainder of the input line to be stored in the string element, regardless of spaces, etc.
A format specification may be used with any of these procedures overriding the default formats. The length of string elements is determined by the format specification (i.e., to read the next 10 characters into a string field, use an A10 format). For more information about format specification, see
"Explicitly Formatted Input and Output".
Unformatted Input and Output in Structures
Reading and writing unformatted data contained in structures is a straightforward process of transferring each element without interpretation or modification, except in the case of strings. Each data type, except strings, has a fixed length expressed in bytes; this length, with the addition of padding, is also the number of bytes read or written for each element.
As with most C compilers, PV‑WAVE pads structure elements to achieve what is called 'natural alignment'. This means that padding is added after each element to ensure that the next element starts on an offset that is a multiple of its size in bytes. Consider this structure definition:
{EXAMPLE, T1: 1B, T2: 1L}
On a 32-bit system, this structure's data requires 8 bytes. Since a PV‑WAVE LONG is 4 bytes on 32-bit systems, 3 bytes must be added after the BYTE tag, T1, to allow T2 to start on a 4-byte boundary. On a 64-bit system, where PV‑WAVE LONGs are 8 bytes, this structure's data requires 16 bytes: 1 byte for T1 followed by 7 bytes of padding to allow T2 to start on an 8-byte boundary.
note | While PV‑WAVE follows this general rule, the actual amount and placement of padding added to align different arrangements of structure elements is platform-specific. Some experimentation can help you to create the most efficient ordering for your structures on your platform. |
String Input and Output
Strings are exceptions to the above rules because the length of strings within structures is not fixed. For example, one instance of the {CATALOG} structure may contain a NAME field with a five-character name, while another instance of the same structure may contain a 20-character name.
When reading into a structure field that contains a string, PV-WAVE reads the number of bytes given by the length of the string. If the string field contains a 10-character string, 10 characters are read. If the data read contains a null byte, the length of the string field is truncated, and the null and following characters are discarded.
When writing fields containing strings with the unformatted procedure WRITEU, PV-WAVE writes each character of the string and does not append a null byte.
String Length Issues
Reading into or writing out of structures containing strings with READU or WRITEU is tricky when the strings are not the same length. For example, it would be difficult for a C program to read variable-length string data written from a PV-WAVE application because PV-WAVE does not append a null byte to the string when it is written out. And from the other side of the coin, it is not possible to read into a string element using READU unless the number of characters to read is known. One way around this problem is to set the lengths of the string elements to some maximum length using the STRING function with a format specification.
For example, it is easy to set the length of all NAME fields in the CAT array to 20 characters:
CAT.NAME = STRING(CAT.NAME, Format='(A20)')
This statement will truncate names larger than 20 characters long and will pad with blanks those names shorter than 20 characters. The structure or structure array may then be output in a format suitable to be read by C or FORTRAN programs.
To read into the CAT array from a file in which each NAME field occupies, for example, 26 bytes:
; Make a 100-element array of CATALOG structures, storing a
; 26-character string in each NAME field.
CAT = REPLICATE( { CATALOG, STRING(' ', $
Format='(A26)'), 0., 0., FLTARR(12) }, 100)
; Read the structure.
READU, 1, CAT
As mentioned above, 26 bytes will be read for each NAME field. The presence of a null byte in the file will truncate the field to the correct number of bytes.