This document briefly desribes a set of glish functions for string and binary data I/O. The motivation is the need to read ASCII catalogs and GBT telescope observing files as well as quick access to simple binary data files. These functions are implemented, in the script rf_client.g, as wrappers for request/reply events recognized by the C++ glish client rf_client.
Many of the functions act very much like their C/C++ counterparts of the same name. In fact, they are implemented with the C/C++ functions after sorting out the differences in glish variable handling. One obvious omission from the list is the scanf() group. This looked like it was going to be harder than the others to write as a client, and most of the scanf() actions can be duplicated with a combination of the fgets() and split_fields() functions along with the native glish split() and as_xxxxx() functions. As of this writing I don't know of a way to read keyboard input from glish since it has tight control of stdin for its interactive commands, and there is no "read_keyboard" command in its library. All of the input functions described here deal with files.
Keep in mind that glish treats string variables very differently than does C/C++. Blank spaces are used as separators between string array elements. Multiple blank spaces together may be treated as only one space. The functions fgets() and split_fields() have a couple of features to help circumvent this, if necessary for fixed format input.
Here is a function summary.
printf ( 'Example: %d %3.1f %s\n', int_var, flt_var, str ) str := sprintf ( 'Example: %d %3.1f', int_var, flt_var ) num_char := fprintf ( file_id, 'Example: %d %3.1f\n', int_var, flt_var ) file_id := fopen ( "myfile.dat", "r" ) fclose ( file_id ) str := fgets ( file_id, '_'[optional] ) array := fread ( file_id, "FLOAT", num_items ) fwrite ( file_id, array ) strx := split_fields ( str, 3, 5, 1,...)
The rf_client.g script, rf_client executable, and C++ source code are in
/hyades1/rfisher/GBTcontrol/Scripts/ClientsIf you are outside of NRAO and would like to get a copy of any of these files, send me an e-mail to the address at the end of this document, and I'll put them in the anonymous ftp area.
printf() closely emulates the C/C++ function of the same name. All of the format specifiers (d, i, o, u, x, X, s, f, e, E, g, G) and their field widths and modifiers are recognized. The format string argument must be in single, not double, quotes for the special characters (\n, \t, etc.) and spaces to be treated correctly. Data type matches with format specifiers are a bit more robust than in C/C++. The variables are converted to the type implied by the format type whenever possible.
Inputs:
Output:
Example: Since every glish function returns something, it's usually a good idea to assign it to a dummy variable to prevent it appearing on the screen in interactive mode or generating a warning message in a script.
xx := printf ( 'Example: %d %3.1f %s\n', int_var, flt_var, str )
sprintf() is identical to printf() except that its output is a returned string variable. Extra spaces will be lost in the string variable.
Inputs:
Output:
Example:
str := sprintf ( 'Example: %d %3.1f', int_var, flt_var )
fprintf() is identical to printf() except that its output is sent to a file. The file must first be opened by fopen(), which returns a file ID used by fprintf().
Inputs:
Output:
Example:
file_id := fopen ( "myfile.dat", "w" ) num_char := fprintf ( file_id, 'Example: %d %3.1f\n', int_var, flt_var ) fclose ( file_id )
fopen() opens a file for reading or writing by fprintf(), fgets(), fread(), or fwrite(). The file ID returned is used by these functions. Up to 32 files may be opened simultaneously. The file(s) should be closed by fclose() when finished reading or writing.
Inputs:
Output:
Example:
file_id := fopen ( "myfile.dat", "r" )
fclose() closes a file opened by fopen(), and the file ID is released for reuse.
Input:
Output:
Example:
file_id := fopen ( "myfile.dat", "r" ) str := fgets ( file_id ) fclose ( file_id )
fgets() reads one line from and ASCII data file, opened by fopen(), up to and including the next end-of-line character (\n). The end-of-line character is deleted from the string that is returned. Repeated use of fgets() reads successive lines. The equivalent of a rewind function can be performed by closing and reopening the file.
The string returned by fgets() is treated like a glish string array, where extra spaces are lost. If character position is important, as in processing a fixed format line, an optional filler character can be specified as a substitute for the blank space character. The string can then be processed by the split_fields() and the filler characters erased by the glish split() function with its break string. See the split_fields() example below.
Inputs:
Output:
Example:
file_id := fopen ( "myfile.dat", "r" ) str := fgets ( file_id, '_' ) fclose ( file_id )
fread() reads the specified number of data values from an unformatted binary file, which has been opened by fopen(). The data type is specified by the second parameter.
Inputs:
Output:
Example:
file_id := fopen ( "mybinary.dat", "r" ) array := fread ( file_id, "float", 100 ) fclose ( file_id )
In glish the byte data type is treated as an unsigned char. If the data file contains signed bytes, the returned array needs to be converted to a short or longer data type and the sign restored with the following construct:
array := fread ( file_id, "byte", 100 ) array := as_short(array) array[array > 127] -:= 256
fwrite() writes a glish data array to the binary file opened by fopen(). The data type written is determined by the glish type of the array. fwrite() is the complement of fread().
Inputs:
Output:
Example:
file_id := fopen ( "mybinary.dat", "w" ) num_written := fwrite ( file_id, array ) if (num_written != length(array)) print "Write error" fclose ( file_id )
split_fields() separates a string into separate elements of a glish string array using specified character field widths. This is useful for parsing a fixed format string that does not contain field delimiters.
Inputs:
Output:
Example:
- print split_fields ( 'abcdefghijklm', 3, 1, 7, 3 ) abc d efghijk lm
To parse a fixed format line from an ASCI file that looks like
sourceX 123456.7 - 534 9first, read the line with fgets() using its filler character to preserve blank spaces. Then divide the line with split_fields(), and erase the filler characters with split().
str := fgets ( file_id, '_' ) str := split_fields ( str, 10, 3, 2, 5, 3, 2, 4 ) str := split ( str, "_" ) str := split ( str ) ra := as_double(str[2]) + as_double(str[3]) / 60.0 + as_double(str[4]) / 3600.0
The second split() gets rid of string elements with only blanks.
This document last updated July 19, 1996.