Lua Formatted File Output
Formatted file output means building each line as text with values placed in fixed positions. string.format builds such a line from a pattern and its values.
Build one formatted line
string.format fills the placeholders with the given values. Write the finished line to the file, then read it back.
local line = string.format("%s is %d years old", "Ada", 36)
local writer = io.open("person.txt", "w")
writer:write(line, "\n")
writer:close()
local reader = io.open("person.txt", "r")
print(reader:read("*l"))
reader:close()Write records as formatted lines
Each record becomes one line with its fields in the same order. A loop writes one line per record.
local records = {
{ name = "Ada", score = 90 },
{ name = "Bo", score = 75 }
}
local writer = io.open("scores.txt", "w")
for i = 1, #records do
writer:write(string.format("%s,%d\n", records[i].name, records[i].score))
end
writer:close()
local reader = io.open("scores.txt", "r")
local line = reader:read("*l")
while line do
print(line)
line = reader:read("*l")
end
reader:close()Read the values back and add them
Each line is split back into a name and a score. Adding the scores proves the numbers survived the round trip.
local writer = io.open("scores.txt", "w")
writer:write("Ada,90\n")
writer:write("Bo,75\n")
writer:close()
local reader = io.open("scores.txt", "r")
local total = 0
local count = 0
local line = reader:read("*l")
while line do
local name, scoreText = string.match(line, "(%a+),(%d+)")
total = total + tonumber(scoreText)
count = count + 1
line = reader:read("*l")
end
reader:close()
print(total)
print(count)Example
local products = {
{ name = "pen", price = 1.50 },
{ name = "book", price = 2.25 },
{ name = "cup", price = 0.75 }
}
local writer = io.open("products.txt", "w")
for i = 1, #products do
writer:write(string.format("%s %.2f\n", products[i].name, products[i].price))
end
writer:close()
local reader = io.open("products.txt", "r")
local total = 0
local count = 0
local line = reader:read("*l")
while line do
local name, priceText = string.match(line, "(%a+) (%d+%.%d+)")
total = total + tonumber(priceText)
count = count + 1
line = reader:read("*l")
end
reader:close()
print(count)
print(string.format("%.2f", total))Key points
- Format pattern: string.format takes a pattern with placeholders and the values to fill them.
- String placeholder: %s stands for a string value in the pattern.
- Integer placeholder: %d stands for a whole number in the pattern.
- Decimal placeholder: %.2f stands for a number with two digits after the point.
- Record line: one formatted line can hold all the fields of one record.
- Round trip: reading a line back and parsing its fields proves the stored values survived.
In this example, the program writes three products as formatted lines with two decimal places. It then reads each line back, parses the price text into a number, and adds the prices. It prints the product count and the total price.
Note
A formatted number is stored as text, so reading it back gives a string until tonumber converts it.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does string.format("%.2f", 2.5) produce?