15. Getting input

So far you have written every value yourself: predictable, but not interactive. This chapter introduces io.read, which waits for the user to type into the terminal.

io.read — read one line

io.read() (no arguments) waits for the user to type a line and press Enter, then returns it as a string without the newline.

print("What is your name?")
local name = io.read()
print("Hello, " .. name)

Run it. It prints the question, waits for your name and Enter, prints the greeting, then exits.

Open exercises/15/01-read-name.lua and run it twice with different names. Watch the greeting change to match.

Prompting on the same line

print always adds a newline. To keep the cursor on the same line, letting the user type next to the prompt, use io.write instead:

io.write("What is your name? ")
local name = io.read()
print("Hello, " .. name)

io.write writes its argument with no newline. Small difference, but the program looks more polished:

What is your name? Keiko
Hello, Keiko

versus the print form:

What is your name?
Keiko
Hello, Keiko

Use either. The book uses io.write for prompts from here on.

Reading a number

io.read() always returns a string, even for digits. To do maths, run it through tonumber:

io.write("Enter a number: ")
local text = io.read()
local n = tonumber(text)
print("Twice that is " .. (n * 2))

The parentheses around n * 2 make the multiplication happen before .. joins it onto the string. Without them, Lua tries to glue 2 onto the string first and gets confused.

If the user types something that is not a number, tonumber returns nil, and maths on nil (nil * 2) is an error. You will fix this in chapter 16 with an if check. For now, just type numbers.

Reading several values

To read several values, call io.read once per value:

io.write("First number:  ")
local a = tonumber(io.read())
io.write("Second number: ")
local b = tonumber(io.read())
print("Sum: " .. (a + b))

Notice the nested call: tonumber(io.read()). The inner call runs first and returns the string; the outer turns it into a number. Same as print(type(x)) from chapter 11 — one function can take another's result directly.

Homework

Problem 1 — Greet by name

Open exercises/15/homework/01-greet-by-name.lua. Prompt for a first name with io.write, read it, then print Hello, <name>!. The exclamation mark is part of the output.

Problem 2 — Sum of two

Open exercises/15/homework/02-sum-of-two.lua. Prompt for two numbers (separate prompts), convert each with tonumber, then print the sum like this:

a + b = c

where a, b, c are the actual values.

Problem 3 — Years to retirement

Open exercises/15/homework/03-retirement.lua. Ask the user's age and compute the years left until 65. Print:

You have N years until retirement.

(If someone is over 65, the number is negative. That is fine — no need to handle that case yet.)

Challenge — BMI

Open exercises/15/homework/04-bmi.lua. Ask for height in metres (a decimal like 1.78) and weight in kilograms (like 72.5). Compute Body Mass Index:

bmi = weight / (height * height)

Print the result rounded to one decimal place with string.format and %.1f. Label it clearly.

Stuck or finished? Open the homework solutions page.