Reading and writing plain text files
by Richard Russell, August 2007
Standard text files, such as are created by text editors like Windows Notepad or MS-DOS EDIT, consist of lines of plain text separated by the character sequence Carriage Return, Line Feed (usually abbreviated as CRLF). Plain text files are probably the most universal of all file formats, especially if you limit their contents to the 7-bit ASCII character set. They can be understood by very many programs, even if not their 'native' file format, and form the basis of many other structured file formats such as Comma Separated Value files.
Although BBC BASIC for Windows does not have built-in support for CRLF-delimited text files it is very easy to read and write files in that format. Since the PRINT# statement delimits string values with Carriage Return (CR) all you need to do to create a standard text file is to add a Line Feed (LF) after each line:
LF = 10 outfile% = OPENOUT(filename$) IF outfile%=0 ERROR 100, "Couldn't create output file "+filename$ PRINT #outfile%, text$ BPUT #outfile%, LF PRINT #outfile%, STR$(number) BPUT #outfile%, LF REM etc. for each line in the file CLOSE #outfile%
Note that numeric values must be written as strings, hence the STR$. For maximum compatibility you should avoid incorporating control characters (i.e. characters with ASCII codes less than 32) other than the CRLF sequence, although often Horizontal Tab characters (HT or CHR$9) will be acceptable.
Similarly, since the INPUT# statement reads string records terminated by CR, all you need to do to read a standard text file is discard the extra LF character if present:
LF = 10 infile% = OPENIN(filename$) IF infile% = 0 ERROR 100, "Couldn't open input file "+filename$ INPUT #infile%, text$ IF ASC(text$) = LF text$ = MID$(text$,2) INPUT #infile%, number$ IF ASC(number$) = LF number$ = MID$(number$,2) number = VAL(number$) REM etc. for each line in the file CLOSE #infile%
Since the LF follows the terminating CR it will appear as the first character in each record (except the first record). Note that numeric values must be read as a string and converted back to a number, hence the VAL.
Line terminations other than CRLF are in use, for example Unix-based file systems generally use a single LF as the line termination; CR and LFCR are also occasionally encountered. If you want to read files in any of these formats you can use the 'universal' FNreadline function below:
DEF FNreadline(F%) LOCAL A$ A$=GET$#F% IF A$="" IF PTR#F%>1 THEN PTR#F%=PTR#F%-2:IF BGET#F%<>BGET#F% A$=GET$#F% = A$
This function will correctly return blank lines, when they are present in the file. If you're not interested in blank lines, and want to discard them, you can use this function instead:
DEF FNreadlinenoblank(F%) LOCAL A$ REPEAT A$=GET$#F% UNTIL A$<>"" OR EOF#F% = A$