std.format.read

This is a submodule of std.format.

It provides two functions for reading formatted input: unformatValue and formattedRead. The former reads a single value. The latter reads several values at once and matches the characters found between format specifiers.

Parameters are ignored, except for the ones consisting of a single '*'. See formattedRead for more information.

A space outside of a format specifier has a special meaning: it matches any sequence of whitespace characters, not just a single space.

The following combinations of format characters and types are available:

scd, u, b, o, x, Xe, E, f, g, Grcompound
boolyesyes
nullyes
integeryesyesyes
floating pointyesyesyes
characteryesyesyes
stringyesyes
arrayyesyes
associative arrayyesyes

Below are highlighted examples on how these combinations are used with unformatValue, however, they apply for formattedRead also

Members

Functions

formattedRead
uint formattedRead(Range r, const(Char)[] fmt, Args args)
uint formattedRead(Range r, Args args)

Reads an input range according to a format string and stores the read values into its arguments.

unformatValue
T unformatValue(Range input, FormatSpec!Char spec)

Reads a value from the given input range and converts it according to a format specifier.

Examples

Booleans

import std.format.spec : singleSpec;

auto str = "false";
auto spec = singleSpec("%s");
assert(str.unformatValue!bool(spec) == false);

str = "1";
spec = singleSpec("%d");
assert(str.unformatValue!bool(spec) == true);

Null values

import std.format.spec : singleSpec;

auto str = "null";
auto spec = singleSpec("%s");
assert(str.unformatValue!(typeof(null))(spec) == null);

Integrals

import std.format.spec : singleSpec;

// signed decimal values
auto str = "123";
auto spec = singleSpec("%s");
assert(str.unformatValue!int(spec) == 123);

// hexadecimal values
str = "ABC";
spec = singleSpec("%X");
assert(str.unformatValue!int(spec) == 2748);

// octal values
str = "11610";
spec = singleSpec("%o");
assert(str.unformatValue!int(spec) == 5000);

// raw read, depends on endianess
str = "\x75\x01";
spec = singleSpec("%r");
auto result = str.unformatValue!short(spec);
assert(result == 373 /* little endian */ || result == 29953 /* big endian */ );

Floating point numbers

import std.format.spec : singleSpec;
import std.math.operations : isClose;

// natural notation
auto str = "123.456";
auto spec = singleSpec("%s");
assert(str.unformatValue!double(spec).isClose(123.456));

// scientific notation
str = "1e17";
spec = singleSpec("%e");
assert(str.unformatValue!double(spec).isClose(1e17));

// raw read, depends on endianess
str = "\x40\x00\x00\xBF";
spec = singleSpec("%r");
auto result = str.unformatValue!float(spec);
assert(isClose(result, -0.5) /* little endian */ || isClose(result, 2.0) /* big endian */ );

Characters

import std.format.spec : singleSpec;

// only the first character is read
auto str = "abc";
auto spec = singleSpec("%s");
assert(str.unformatValue!char(spec) == 'a');

// using a numerical format character treats the read number as unicode code point
str = "65";
spec = singleSpec("%d");
assert(str.unformatValue!char(spec) == 'A');

str = "41";
spec = singleSpec("%x");
assert(str.unformatValue!char(spec) == 'A');

str = "10003";
spec = singleSpec("%d");
assert(str.unformatValue!dchar(spec) == '✓');

Arrays

import std.format.spec : singleSpec;

// string value
string str = "aaa";
auto spec = singleSpec("%s");
assert(str.unformatValue!(dchar[])(spec) == "aaa"d);

// fixed size array with characters
str = "aaa";
spec = singleSpec("%s");
dchar[3] ret = ['a', 'a', 'a'];
assert(str.unformatValue!(dchar[3])(spec) == ret);

// dynamic array
str = "[1, 2, 3, 4]";
spec = singleSpec("%s");
assert(str.unformatValue!(int[])(spec) == [1, 2, 3, 4]);

// fixed size array with integers
str = "[1, 2, 3, 4]";
spec = singleSpec("%s");
int[4] ret2 = [1, 2, 3, 4];
assert(str.unformatValue!(int[4])(spec) == ret2);

// compound specifiers can be used for more control
str = "1,2,3";
spec = singleSpec("%(%s,%)");
assert(str.unformatValue!(int[])(spec) == [1, 2, 3]);

str = "cool";
spec = singleSpec("%(%c%)");
assert(str.unformatValue!(char[])(spec) == ['c', 'o', 'o', 'l']);

Associative arrays

import std.format.spec : singleSpec;

// as single value
auto str = `["one": 1, "two": 2]`;
auto spec = singleSpec("%s");
assert(str.unformatValue!(int[string])(spec) == ["one": 1, "two": 2]);

// with compound specifier for more control
str = "1/1, 2/4, 3/9";
spec = singleSpec("%(%d/%d%|, %)");
assert(str.unformatValue!(int[int])(spec) == [1: 1, 2: 4, 3: 9]);

Meta