=====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 [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwinb.html#ascii|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 [[/Reading%20and%20writing%20CSV%20files|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 [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwin7.html#printhash|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 [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwin7.html#str|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 [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwin5.html#inputhash|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 [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwin7.html#val|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$