[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
strfmon in the C locale
From: |
Bruno Haible |
Subject: |
strfmon in the C locale |
Date: |
Sat, 23 Sep 2017 10:50:07 +0200 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-93-generic; KDE/5.18.0; x86_64; ; ) |
Test program:
=======================================================================
#include <locale.h>
#include <monetary.h>
#include <stdio.h>
int main ()
{
char buf[80];
printf ("currency = |%s|\n", localeconv()->currency_symbol);
printf ("positive sign = |%s|\n", localeconv()->positive_sign);
printf ("negative sign = |%s|\n", localeconv()->negative_sign);
strfmon (buf, sizeof (buf), "%^#5.0n", 123.4);
printf ("strfmon result for positive value = |%s|\n", buf);
strfmon (buf, sizeof (buf), "%^#5.0n", -123.4);
printf ("strfmon result for negative value = |%s|\n", buf);
}
=======================================================================
Results
=======
Result on glibc 2.23:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = | 123|
strfmon result for negative value = |- 123|
Result on Solaris 10:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = | 123|
strfmon result for negative value = |- 123|
Result on Mac OS X 10.12:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = | 123 |
strfmon result for negative value = |( 123)|
Discussion
==========
The POSIX spec is at [1].
I don't think the Mac OS X 10.12 result is correct because the test
program does not specify the '+' nor '(' flag, and POSIX says
If '+' is specified, the locale's equivalent of '+' and '-' are
used (for example, in many locales, the empty string if positive and '-'
if negative). If '(' is specified, negative amounts are enclosed within
parentheses. If neither flag is specified, the '+' style is used.
I don't think the glibc and Solaris results are correct because they
show a '-' sign, although localeconv()->negative_sign is the empty
string (which is mandated by POSIX [2]).
The Solaris result is worse than the glibc one, because it produces
a different number of characters in the negative and in the positive
case, which is against what POSIX says for the '#' flag:
To ensure alignment, any characters appearing before or after the
number in the formatted output such as currency or sign symbols are
padded as necessary with <space> characters to make their positive
and negative formats an equal length.
The result I would have expected is therefore:
currency = ||
positive sign = ||
negative sign = ||
strfmon result for positive value = | 123|
strfmon result for negative value = | 123|
Conclusion
==========
strfmon in the C locale is unusable. strfmon in territory locales is
probably not much better.
I won't spend time to add workarounds for it, because
* C is a system programming language, while strfmon is for
applications. Applications nowadays are not being written in C
any more (except in GNOME).
* Especially applications that deal with money. Given the amount
of programming mistakes one can do in C and the amount of
security vulnerabilities that C programs have on average
(compared to other programming languages), who would want to
to write monetary applications in C?
Bruno
[1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/strfmon.html
[2]
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap07.html#tag_07_03_03_01
- strfmon in the C locale,
Bruno Haible <=