strfmon(3)
π strfmon β string format monetary value π
okay bestie, gather round, because today we're learning about strfmon and strfmon_l, the two little libc girlies who take your money and make it pretty. They format monetary amounts into strings. yes. that's the whole job. and they ate.
β¨ NAME β¨
strfmon, strfmon_l β string format monetary value πΈ
π LIBRARY π
Standard C library (libc, -lc). she's standard, she's built in, she's everywhere. periodt.
π«Ά SYNOPSIS π«Ά
#include <monetary.h>
ssize_t strfmon(size_t size;
char s[restrict size], size_t size,
const char *restrict format, ...);
ssize_t strfmon_l(size_t size;
char s[restrict size], size_t size, locale_t l,
const char *restrict format, ...);
π DESCRIPTION π
so strfmon() takes the monetary amount you hand it, formats it according to the current locale plus whatever format spec you gave, and drops the result into the character array s, which is exactly size bytes long. cute, right?
strfmon_l() does the exact same thing, except it uses the locale you specify with l instead of whatever the current one is. π¦
β οΈ okay real talk though: the behavior ofstrfmon_l()is undefined iflis the special locale objectLC_GLOBAL_LOCALE(peepduplocale(3)for that) or iflisn't a valid locale object handle at all. not a vibe. don't do it.
Anyway. Ordinary characters sitting in format get copied straight into s with no conversion whatsoever β they're just chillin'. Conversion specifiers, though? Those get introduced by a % character. and immediately after that %, you can have zero or more of these flags:
=fβ the single-byte characterfbecomes your numeric fill character. (yes, that's what you use with a left precision, more on that in a sec.) if you never specify one, the space characteris the default. classic.^β do not use any grouping characters that might be defined for the current locale. by default, grouping is enabled, so this flag is you saying "bestie, no commas today". π(or+β the(flag means negative amounts get wrapped in parentheses, like they're being gently held. the+flag means signs get handled the default way, meaning amounts are preceded by the locale's sign indication β for example, nothing for positive, and"-"for negative. π!β omit the currency symbol entirely. no dollar sign, no euro, no vibes. π-β left justify all fields. the default is right justification, so this is the flag that flips the whole attitude.
Next up, there may be a field width: a decimal digit string that specifies a minimum field width in bytes. the default is 0. if your result is smaller than this width, it gets padded with spaces β on the left, unless you gave that left-justify flag. slay.
Then there may be a left precision, which looks like # followed by a decimal digit string. if the number of digits to the left of the radix character is smaller than this, the representation gets padded on the left with the numeric fill character. heads up: grouping characters are not counted in this field width. math said no. π
Then there may be a right precision, which looks like . followed by a decimal digit string. the amount being formatted gets rounded to the specified number of digits before formatting. the default comes straight from the frac_digits and int_frac_digits items of the current locale. if the right precision is 0, no radix character is printed at all. (fun fact: the radix character here is determined by LC_MONETARY, and it may differ from the one specified by LC_NUMERIC. iykyk.)
Finally β and this is the part you cannot skip β the conversion specification must be ended with a conversion character. there are exactly three, and they're kind of iconic:
%β in this case, the entire specification must be exactly"%%". it puts a%character into the result string. that's it. that's the whole gig.iβ one argument of typedoublegets converted using the locale's international currency format. πnβ one argument of typedoublegets converted using the locale's national currency format. π
π₯ RETURN VALUE π₯
strfmon() returns the number of characters placed in the array s, not including the terminating null byte β as long as the string, including that terminating null byte, fits. π«Ά
if it doesn't fit? she sets errno to E2BIG, returns -1, and the contents of the array become undefined. so like, don't read it. it's giving mystery box. don't open it.
π ATTRIBUTES π
for an explanation of the terms used in this section, peep attributes(7). here's the rundown:
strfmon()β Thread safety:MT-Safe localestrfmon_l()β Thread safety:MT-Safe
π STANDARDS π
POSIX.1-2008. certified. official. she has papers. π
πΈ HISTORY πΈ
POSIX.1-2001. she's been around, okay? an OG.
π EXAMPLES π
okay so the call
strfmon(buf, sizeof(buf), "[%^=*#6n] [%=*#6i]",
1234.567, 1234.567);
outputs
[β¬ **1234,57] [EUR **1 234,57]
in the nl_NL locale. π§ and the de_DE, de_CH, en_AU, and en_GB locales yield:
[ **1234,57 β¬] [ **1.234,57 EUR]
[ Fr. **1234.57] [ CHF **1'234.57]
[ $**1234.57] [ AUD**1,234.57]
[ Β£**1234.57] [ GBP**1,234.57]
look at all those currencies. the range. the versatility. we love to see it. π
π¦ SEE ALSO π¦
duplocale(3), setlocale(3), sprintf(3), locale(7)
and that's the whole page, bestie!! no cap, every detail intact, every flag accounted for, nothing skipped. this was Linux man-pages 6.20, dated 2026-07-26, and honestly? she devoured. π β¨π byeeee π«Ά
π¦ where this page comes from
- arch rolling: man-pages 6.20-1 Β· BSD-2-Clause AND BSD-3-Clause AND BSD-4.3TAHOE AND BSD-4-Clause-UC AND GPL-1.0-or-later AND GPL-2.0-only AND GPL-2.0-or-later AND GPL-3.0-or-later AND LGPL-3.0-linking-exception AND LGPL-3.0-or-later AND LicenseRef-Public-Domain AND LicenseRef-UltraPermissive AND Linux-man-pages-1-para AND Linux-man-pages-copyleft AND Linux-man-pages-copyleft-2-para AND Linux-man-pages-copyleft-var AND MIT AND Spencer-94
- nixpkgs unstable: man-pages 6.20
- π the page's license: GPL-2.0-or-later
- Copyright 2000, Andries E. Brouwer <aeb@cwi.nl>
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms