Handling CR line ends in Lua

I am trying to read a file with the end of a CR line using the file:read method, which for some reason seems to work. The contents of the file are as follows:

 ABCDEFGH 12345 ## 6789 

I want him to behave consistently with all types of line endings. Each time I try to read a file, it returns the last line in the file, combined with any trailing characters from previous lines that have a greater position than the position of the last character in the last line. Here is what I mean:

 > file=io.open("test.lua", "rb") > function re_read(openFile) openFile:seek("set"); return openFile:read("*a"); end > =re_read(file) -- With CR 67895FGH > =re_read(file) -- With CRLF ABCDEFGH 12345 ## 6789 > =re_read(file) -- with LF ABCDEFGH 12345 ## 6789 > 

As you can see, the returned row is the last row plus 5 in the previous row and plus FGH from the first row. Any lines shorter than the last line are skipped.

My goal is to use the file:line() method to read a file line by line. I hope that if "fix" for file:read is found, it can be applied to file:lines() .

+6
source share
2 answers

In the case of only CR, re_read works fine, it returns strings separated by CR. But when the interpreter displays it, it interprets the CR characters as "return to the beginning of the line." So here is how the result changes line by line:

 ABCDEFGH 12345FGH ##345FGH 67895FGH 

EDIT: here it is character by character, with a "virtual cursor" ( | ).

 | A| AB| ABC| ABCD| ABCDEF| ABCDEFGH| |ABCDEFGH 1|BCDEFGH 12|CDEFGH 123|DEFGH 1234|EFGH 12345|FGH |12345FGH #|2345FGH ##|345FGH |##345FGH 6|#345FGH 67|345FGH 678|45FGH 6789|5FGH 

Evidence:

 > s = "ABCDEFGH\r12345\r##\r6789" > =s 67895FGH 
+6
source

You can normalize the line ending with gsub and then gmatch over the product with gmatch .

 local function cr_lines(s) return s:gsub('\r\n?', '\n'):gmatch('(.-)\n') end local function cr_file_lines(filename) local f = io.open(filename, 'rb') local s = f:read('*a') f:close() return cr_lines(s) end for ln in cr_file_lines('test.txt') do print(ln) end 
+3
source

All Articles