Reading Text Files a Character at a Time

You can use the CHARIN and other character methods on text files. Because you read the file as characters CHARIN returns the line-end characters to your program. Line methods, on the contrary, do not return the line-end characters to your program.

The line-end characters on Windows consist of a carriage return (ASCII value of 13) and a line feed (ASCII value of 10). The line-end characters on Unix/Linux consist of a line feed (ASCII value of 10). Rexx adds these characters to the end of every line written using the LINEOUT method. Text-processing applications, such as the Windows Notepad, also add the characters. When reading a text file with CHARIN, interpret an ASCII sequence of 13 followed by 10 as the end of a line.

As an example, run the following program. It writes lines to a file using LINEOUT and then reads those lines using CHARIN. You can mix line methods and character methods. Rexx maintains separate read and write pointers, so there is no need to close the file or search for another position before reading the lines just written.

/* LINECHAR.CMD - demonstrate line end characters                   */
file=.stream~new("test.dat")  /* Create a new stream object         */

file~open("both replace")  /* Open the file for reading and writing */
do i=1 to 3                /* Write three lines to the file         */
   file~lineout("Line" i)
end /* do */

do while file~chars<>0     /* Read the file a character at a time   */
   byte=file~charin        /* Read a character                      */
   ascii_value=byte~c2d    /* Convert character to a decimal value  */
   if ascii_value=13 then        /* Carriage return?                */
      say "Carriage return"
   else if ascii_value=10 then   /* Line feed?                      */
      say "Line feed"
   else say byte ascii_value     /* Ordinary character              */
end /* do */
file~close                       /* Close the file                  */

Some text-processing programs also write an end-of-file character (ASCII value 26) after the last line. You can check for that character also when processing text files with character methods. The following program shows how to handle EOF characters in files.

/* EOFCHAR.CMD - demonstrate end-of-file characters                 */
file=.stream~new("test.dat")  /* Create a new stream object         */

do while file~chars<>0     /* Read the file a character at a time   */
   byte=file~charin        /* Read a character                      */
   ascii_value=byte~c2d    /* Convert character to a decimal value  */
   if ascii_value=13 then        /* Carriage return?                */
      say "Carriage return"
   else if ascii_value=10 then   /* Line feed?                      */
      say "Line feed"
   else if ascii_value=26 then   /* End of file?                    */
      say "End of File"
   else say byte ascii_value     /* Ordinary character              */
end /* do */

Rexx does not write end-of-file characters when it closes a file that has been opened for writing.

It is not recommended to use line methods to read binary files. Your binary file might not contain any new-line characters. And, if it did, the characters probably are not meant to be interpreted as new-line characters.