Skip to main content

format(formatString)

Formats and returns a string for display

Availability

Device + Agent

Parameters

Name Type Description
formatString String A format string containing C printf format codes and standard escape codes

Returns

String

Description

This function composes a printable string from a combination of string literals, format placeholders, escape sequences and non-string data values.

Because format() is implemented as a function, it does not use dot syntax.

The function uses the standard C language printf format placeholders though not all of these are relevant to Squirrel's data types. Those that are are listed in the table below:

Code Data Type Description
%x Integer Presents a hexadecimal number with lower-case letters
%X Integer Presents a hexadecimal number with upper-case letters
%o Integer Presents an octal number
%u Integer Presents an unsigned decimal value
%i Integer Presents a signed decimal value
%d Integer Presents a signed decimal value
%f Float Presents a decimal value in floating-point format
%e Float Presents a decimal value in scientific notation
%g Float Use the shortest representation: %e or %f
%s String Presents a string
%c Integer Presents an integer value as a character
%% N/A Percentage symbol

Note Squirrel's implementation of format() allows zeros to be included in the format string itself but not in any input string to be formatted. This is because, even though Squirrel strings are not NUL terminated (ie. terminated with 0), format() uses C’s printf command and so treats zeros in strings as terminators. For example:

local start = "First";
local mid = "\x26\x00\x4C";
local end = "ast&Always";
local combined = format("%s%s%s", start, mid, end);
server.log(combined);

A Squirrel programmer might expect the output to be First&Last&Always, but in fact it is First&ast&Always. This is because printf treats the "\x00" within mid as the end of the string; the L ("\x4C") is therefore never interpolated into the output string.

The floating point options defaults to six decimal places of precision, but this can be changed by adding .x after the % sign, where x is the desired number of decimal places you require. For example:

local a = format("%.4e", 452.73961);
server.log(a);
// Displays "4.5274e+02"

and

local a = format("%.2f", 452.73961);
server.log(a);
// Displays "452.74"

The same approach can be used to ‘pad’ integer values with spaces or zeroes. Here the period is omitted — to pad with spaces — or replaced with a zero:

local a = format("%6u", 45);
server.log(a);
// Displays "    45"

and

local a = format("%02u", 4);
server.log(a);
// Displays "04"

Padding with zeroes is particularly useful when you are working with hexadecimal notation:

local a = format("%04X", 15);
server.log(a);
// Displays "000F"

Because the format string can also contain literal string characters, the hexadecimal number can be presented in the customary way by adding 0x to the start of the format string:

local a = format("0x%02X", 15);
server.log(a);
// Displays "0x0F"

As you can see from the examples above, the value to be substituted for the placeholder is written after the format string, separated by a comma. Multiple placeholders can be added to the format string, and their substitution values placed after the format string accordingly. All are separated by commas. Values can be variables as well as literal values:

local number = 20;
local a = format("My favourite device is the %s. I own %d of them.", "imp", number);
server.log(a);
// Displays "My favourite device is the imp. I have 20 of them."

When Squirrel detects a placeholder, it replaces that placeholder with the next value (or variable) in sequence. So the order in which values are placed is important. So too is matching the placeholder to the data type — Squirrel will post an error if placeholder and value don’t match, for example ‘string expected for the specified format’.

The format string may also contain the standard C-language escape sequences for characters that have special meaning for Squirrel and might otherwise be misinterpreted:

  • \\ Backward slash
  • \" Double quote mark
  • \' Single quote mark
  • \n New line
  • \r Carriage Return
  • \b Backspace
  • \t Tab
  • \x This marks the two characters that follow as a single-byte hexadecimal number

Following a single backslash with one, two or three numeric characters will prompt Squirrel to treat them as a octal value.

For imp programmers, the \x sequence is particularly useful for configuring API calls for communicating with I²C, SPI and other devices using strings. The sequence allows you to format these strings with correct 8-bit 'char' values rather than Squirrel's default 32-bit integer values:

local register = "\xF0";             // String contains a single 8-bit value, 240
local number = 0x42;
local dataOne = number.tostring();   // String contains two eight-bit char values: 6 and 6
local dataTwo = number.tochar();     // String contains a single 8-bit char value, 66

// Send the sigle-byte value 66 to the device's register via i2c

// This will not the desired effect...
hardware.i2c12.write(i2cAddress, register + dataOne);

// ... but this will
hardware.i2c12.write(i2cAddress, register + dataTwo);

As we saw earlier, you can then use format() to convert strings read back from I²C and other buses to true numerical values.