Task

Read a file one character at a time, as opposed to reading the entire file at once.

The solution may be implemented as a procedure, which returns the next character in the file on each consecutive call (returning EOF when the end of the file is reached).

The procedure should support the reading of files containing UTF8 encoded wide characters, returning whole characters for each consecutive read.

Related task

   Read a file line by line


 
Module checkit {
      \\ prepare a file
      \\ Save.Doc and Append.Doc  to file, Load.Doc and Merge.Doc from file
      document a$
      a$={First Line
            Second line
            Third Line
            Ελληνικά Greek Letters
            yä®€
            成长汉
            }
      Save.Doc a$, "checkthis.txt", 2  ' 2 for UTF-8
      b$="*"
      final$=""
      buffer Clear bytes as byte*16
      Buffer One as byte
      Buffer Two as byte*2
      Buffer Three as byte*3
      Locale 1033
      open "checkthis.txt" for input as #f
      seek#f, 4 ' skip BOM
      While b$<>"" {
            GetOneUtf8Char(&b$)
            final$+=b$
      }
      close #f
      Report final$
      Sub GetOneUtf8Char(&ch$)
            ch$=""
            if Eof(#f) then Exit Sub
            Get #f, One
            Return Bytes, 0:=Eval(one, 0)
            local mrk=Eval(one, 0)
           Try ok {
                  If Binary.And(mrk, 0xE0)=0xC0 then {
                        Get #f,one
                        Return Bytes, 1:=Eval$(one, 0,1) 
                        ch$=Eval$(Bytes, 0, 2)
                  } Else.if Binary.And(mrk, 0xF0)=0xE0 then {
                        Get #f,two
                        Return Bytes, 1:=Eval$(two,0,2)
                        ch$=Eval$(Bytes, 0, 3)
                  } Else.if Binary.And(mrk, 0xF8)=0xF0 then {
                        Get #f,three
                        Return Bytes, 1:=Eval$(three, 0, 3)
                        ch$=Eval$(Bytes, 0, 4)
                  } Else ch$=Eval$(Bytes, 0, 1)
            }
            if Error or not ok then ch$="" : exit sub
            ch$=left$(string$(ch$ as Utf8dec),1)
      End Sub
}
checkit
 