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


#helper function that deals with non-ASCII code points
local (read-utf8-char) file tmp:
    !read-byte file
    if = :eof dup:
        drop
        raise :unicode-error
    resize-blob tmp ++ dup len tmp
    set-to tmp
    try:
        return !decode!utf-8 tmp
    catch unicode-error:
        if < 3 len tmp:
            raise :unicode-error
        (read-utf8-char) file tmp
 
#reader function
read-utf8-char file:
    !read-byte file
    if = :eof dup:
        return
    local :tmp make-blob 1
    set-to tmp 0
    try:
        return !decode!utf-8 tmp
    catch unicode-error:
        (read-utf8-char) file tmp
 
#if the module is used as a script, read from the file "input.txt",
#showing each code point separately
if = (name) :(main):
    local :file !open :read "input.txt"
 
    while true:
        read-utf8-char file
        if = :eof dup:
            drop
            !close file
            return
        !.