C/POSIX conforming sprintf implementation in JavaScript
npm install agh.sprintfC, POSIX compatible sprintf written in JavaScript.
License: MIT License
See 日本語の説明 for the Japanese README texts.
HTML
``html`
Node
`sh`
$ npm install agh.sprintf
`javascript`
const agh = require('agh.sprintf');
console.log(agh.sprintf("pi = %-.g / this is an example /", 30, 20, Math.PI));
console.log(agh.vsprintf("pi = %-.g / this is an example /", [30, 20, Math.PI]));
Node (without npm)
`sh`
$ git clone https://github.com/akinomyoga/agh.sprintf.js
$ cd agh.sprintf.js
`javascript`
const agh = require('./agh.sprintf.js');
console.log(agh.sprintf("pi = %-.g / this is an example /", 30, 20, Math.PI));
console.log(agh.vsprintf("pi = %-.g / this is an example /", [30, 20, Math.PI]));
The first argument of sprintf is a format string which may include the following form of format specifiers:
'%' \
- The conversion specifier \
- The width specifier \
- The precision specifier \
- The flags \
- The position parameter \
- The size specifier \
A conversion specifier determines the interpretation of an argument and the format of the output.
|Specifier|Standard|Description|
|:--|:--|:--|
|'d', 'i'|ANSI C|decimal signed number'o'
| |ANSI C|octal unsigned number'u'
| |ANSI C|decimal unsigned number'x', 'X'
||ANSI C|hexadecimal unsigned number. lower/upper case corresponds to, e.g., 0xa/0XA.'f', 'F'
||ANSI C|floating point numbers. lower/upper case corresponds to, e.g., inf/INF.'e', 'E'
||ANSI C|floating point numbers by the scientific representation. lower/upper case corresponds to, e.g., 1e+5/1E+5.'g', 'G'
||ANSI C|floating point numbers with the specified precision.'a', 'A'
||C99 |floating point numbers in hexadecimal.'c'
| |ANSI C|character'C'
| |XSI |character (same as 'c' in this implementation. Originally, the argument is interpreted as wchar_t.)'s'
| |ANSI C|string'S'
| |XSI |string (same as 's' in this implementation. Originally, the argument is interpreted as wchar_t)'p'
| |ANSI C|pointer (same as %#x in this implementation)'n'
| |ANSI C|stores to value[0] the number of the characters output until this point'%'
| |ANSI C|output "%"
`javascript`
// Examples
agh.sprintf("%d", 12345); // "12345"
agh.sprintf("%o", 12345); // "30071"
agh.sprintf("%u", -12345); // "4294954951"
agh.sprintf("%x", 54321); // "d431"
agh.sprintf("%X", 54321); // "D431"
agh.sprintf("%f", Math.PI); // "3.141593"
agh.sprintf("%e", Math.PI); // "3.141593e+000"
agh.sprintf("%g", Math.PI); // "3.14159"
agh.sprintf("%a", Math.PI); // "0x1.921fb54442d18p+001"
agh.sprintf("%f, %F", Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY); // "inf, INF"
agh.sprintf("%c, %C", 12354, 12354); // "あ, あ"
agh.sprintf("%s, %S", 12354, 12354); // "12354, 12354"
agh.sprintf("%d", 12345); // "12345"
agh.sprintf("%p", 12345); // "0x3039"
agh.sprintf("%d%n", 12345, a = []); // "12345", a == [5]
agh.sprintf("%%"); // "%"
The width specifier has the following form:
\ | '' | '' /\d+/ '$'
| Specifier | Standard | Description |
|:--|:--|:--|
|/\d+/ |ANSI C|The minimal width is directly specified.|'*'
| |ANSI C|The next argument is consumed for the minimal width.|'*'
| /\d+/ '$'|POSIX|The argument specified with the index is used for the minimal width.|
`javascript`
// Examples
agh.sprintf("[%1d]", 12345); // "[12345]"
agh.sprintf("[%8d]", 12345); // "[ 12345]"
agh.sprintf("[%*d]", 6, 12345); // "[ 12345]"
agh.sprintf("[%*2$d]", 12345, 7); // "[ 12345]"
The precision specifier has the following form:
\ /\d+/ | '.' | '.' /\d+/ '$'
|Specifier|Standard|Description|
|:--|:--|:--|
|'.' /\d+/ |ANSI C|The precision is directly specified.'.*'
| |ANSI C|The next argument is consumed for the precision.'.*'
| /\d+/ '$'|POSIX |The argument specified with the index is used for the precision.
In the case of the integer converesions (\" will be ignored.
In the case that \
For the strings \
`javascript`
// Examples
agh.sprintf("%.1d", 12345); // "12345"
agh.sprintf("%.8d", 12345); // "00012345"
agh.sprintf("%.*d", 6, 12345); // "012345"
agh.sprintf("%.*2$d", 12345, 7); // "0012345"
agh.sprintf("%.1f", Math.PI); // "3.1"
agh.sprintf("%.10f", Math.PI); // "3.1415926536"
agh.sprintf("%.50f", Math.PI); // "3.14159265358979311599796346854418516159057617187500"
agh.sprintf("%.1g", Math.PI); // "3"
agh.sprintf("%.10g", Math.PI); // "3.141592654"
agh.sprintf("%.1s", "12345"); // "1"
agh.sprintf("%.10s", "12345"); // "12345"
The flag specifier has the following form:
\ | /\=./ ) +
| Flag | Standard | Description |
|:--|:--|:--|
|'-'|ANSI C|The left justification instead of the default of the right justification|'+'
||ANSI C|The plus sign for positive numbers|'#'
||ANSI C|For the integer conversions, the prefix representing its base will be added if the value is not zero. The prefixes are "0", "0x", and "0X" for \' '
For the floating point numbers, this flag prevent to omit the decimal point even if the value is an integer. In addition, trailing zeroes will not be omitted for \
||ANSI C|A space is output at the sign position for positive numbers. This space is not omitted even if the output width excesses the specified \'0'
||ANSI C|Use "0" instead of " " for the left padding. Note that, unlike the spaces, 0s are inserted after the sign and the prefixes.|"'"
||SUSv2|The grouping characaters, i.e. commas at every three digits, are inserted in the integral part for \0".|
`javascript`
// Examples
agh.sprintf("[%3d][%-3d]", 1, 1); // "[ 1][1 ]"
agh.sprintf("%d, %+d", 1, 1); // "1, +1"
agh.sprintf("%o, %#o, %#o", 1, 1, 0); // "1, 01, 0"
agh.sprintf("%x, %#x, %#x", 1, 1, 0); // "1, 0x1, 0"
agh.sprintf("[%d][% d]", 1, 1); // "[1][ 1]"
agh.sprintf("[%4d][%04d]", 1, 1); // "[ 1][0001]"
agh.sprintf("%d, %'d", 1234567, 1234567); // "1234567, 1,234,567"
The positional parameter has the following form:
\
It selects an argument to output by its index. The argument just after the format string corresponds to the index 1.
`javascript`
// Example
agh.sprintf("%3$d %2$d %1$d %2$d %3$d", 111, 222, 333); // "333 222 111 222 333"
The size specifier determines the exact type of the argument, e.g. the binary representation of the integers and the floating point numbers. The size specifier has a different meaning for each conversion:
For the integers (\
|Size |Standard (typical meaning)|Implementation|
|:------|:-----------------------|:-----|
|(default)|ANSI C (int) |double|
|'hh' |C99 (char) | 8bit|'h'
| |ANSI C (short) | 16bit|'l'
| |ANSI C (long) | 32bit|'ll'
| |C99 (long long) | 32bit|'t'
| |C99 (ptrdiff_t) | 32bit|'z'
| |C99 (size_t) | 32bit|'I'
| |MSVC (ptrdiff_t, size_t)| 32bit|'I32'
||MSVC (32bit) | 32bit|'q'
| |BSD (64bit) | 64bit|'I64'
||MSVC (64bit) | 64bit|'j'
| |C99 (intmax_t) |double|
- If nothing is specified, the integer can be double value since the internal representation of the integers is double in JavaScript.q
- The bit width for ptrdiff_t, size_t, long, and long long is 32 bits because the JavaScript integer does not have the precision of 64 bits.
- The explicit 64 bit specifiers, and I64, may not result in correct output.
`javascript`
// Examples
agh.sprintf("%x", 123456789); // "75bcd15"
agh.sprintf("%hx", 123456789); // "cd15"
agh.sprintf("%hhx", 123456789); // "15"
For the floating point numbers (\
|Size |Standard |Description|
|:------|:-----------------------|:-----|
|(default) |ANSI C (double) |double|
|'hh' |Original | float|'h'
| |Original | float|'l'
| |C99 (double) |double|'ll'
| |Original |double|'L'
| |ANSI C (long double) |double|'w'
| |Original |double|
- The type double is used instead of long double since JavaScript does not have the type.hh
- The sizes , h, l, ll, and w are used for other conversions in standards.
`javascript`
// Examples
agh.sprintf("%.15g", Math.PI); // "3.14159265358979"
agh.sprintf("%.15hg", Math.PI); // "3.14159250259399"
For characters and strings (\
|Size |Standard |Description |
|:-----|:--------------|:------|
|(default)|ANSI C |unicode|
|'hh'|Original | ascii|'h'
| |MSVC (char) | ascii|'l'
| |C99 (wint_t) |unicode|'w'
| |MSVC (wchar_t) |unicode|
`javascript`
// Examples
agh.sprintf("%c", 12354); // "あ"
agh.sprintf("%hc", 12354); // "B"
README: Comparisions with other implementations?
sprintf.js: Padding character specifier =?`, Named arguments, filters