如何在C语言中使用逗号格式化货币?

5

我希望在C语言中将一个长浮点数格式化为货币形式。我想在数字前面放置美元符号,在小数点前每隔三位数字就加上逗号,并在小数点前紧跟一个点号。到目前为止,我已经按如下方式打印数字:

printf("You are owed $%.2Lf!\n", money);

返回类似以下内容的东西

You are owed $123456789.00!

数字应该像这样显示:

这样


$123,456,789.00
$1,234.56
$123.45

任何答案都不需要是实际的代码。你不必喂食。如果有C相关的具体信息会有帮助,请提及。否则伪代码也可以。


2
请参见以下链接:https://dev59.com/QHM_5IYBdhLWcg3wRw51 - philipvr
谢谢你,这也很有帮助。 - ironicaldiction
1
我知道这有点超出了你的问题范围,但是你可能找不到一种常见的方法来做到这一点,因为将货币值存储为浮点数通常不是一个好主意。 - argentage
可能存在精度误差的原因? - ironicaldiction
+1 @airza。积极主动 - 是的,在二进制/十进制转换中,分数表现不佳。最好将值存储为整数的分(cents)。 - Carl Norum
5个回答

11

你的 printf 可能已经可以使用 ' 标志来实现这个功能。但你可能需要设置你的语言环境。以下是我的机器上的示例:

#include <stdio.h>
#include <locale.h>

int main(void)
{
    setlocale(LC_NUMERIC, "");
    printf("$%'.2Lf\n", 123456789.00L);
    printf("$%'.2Lf\n", 1234.56L);
    printf("$%'.2Lf\n", 123.45L);
    return 0;
}

然后运行它:

> make example
clang -Wall -Wextra -Werror    example.c   -o example
> ./example 
$123,456,789.00
$1,234.56
$123.45

我在我的 Mac (10.6.8) 和我刚试过的一台 Linux 机器 (Ubuntu 10.10) 上运行这个程序,都能按照你期望的方式工作。


这在我的Ubuntu系统上检查通过。谢谢啦。 - ironicaldiction
这是 POSIX 所要求的 — printf() - Jonathan Leffler

2

我知道这是一个早期的帖子,但今天我陷入了"man"兔子洞,所以我想记录一下我的经历:

有一个名为 "strfmon()" 的函数,您可以使用 monetary.h 包含它来完成此操作,并根据本地或国际标准执行此操作。

请注意,它像 printf() 一样工作,并将采用与字符串中指定的 % 格式相同数量的 double 参数。

除了我在这里提到的内容外,还有更多内容,我发现这个页面最有帮助:https://www.gnu.org/software/libc/manual/html_node/Formatting-Numbers.html

原始答案:Original Answer

#include <monetary.h>
#include <locale.h>
#include <stdlib.h>
#include <stdio.h>

int main(){
    // need to setlocal(), "" sets locale to the system locale
    setlocale(LC_ALL, "");

    double money_amt = 1234.5678;

    int buf_len = 16;
    char simple_local[buf_len];
    char international[buf_len];
    char parenthesis_for_neg[buf_len];
    char specified_width[buf_len];
    char fill_6_stars[buf_len];
    char fill_9_stars[buf_len];
    char suppress_thousands[buf_len];

    strfmon(simple_local, buf_len-1, "%n", money_amt);
    strfmon(international, buf_len-1, "%i", money_amt);
    strfmon(parenthesis_for_neg, buf_len-1, "%(n", money_amt);
    strfmon(specified_width, buf_len-1, "%#6n", money_amt);
    strfmon(fill_6_stars, buf_len-1, "%=*#6n", money_amt);
    strfmon(fill_9_stars, buf_len-1, "%=*#8n", money_amt);
    strfmon(suppress_thousands, buf_len-1, "%^=*#8n", money_amt);

    printf( "===================== Output ===================\n"\
            "Simple, local:                  %s\n"\
            "International:                  %s\n"\
            "parenthesis for negatives:      %s\n"\
            "fixed width (6 digits):         %s\n"\
            "fill character '*':             %s\n"\
            "-- note fill characters don't\n"\
            "-- count where the thousdands\n"\
            "-- separator would go:\n"\
            "filling with 9 characters:      %s\n"\
            "Suppress thousands separators:  %s\n"\
            "================================================\n",
            simple_local, international, parenthesis_for_neg,
            specified_width, fill_6_stars, fill_9_stars,
            suppress_thousands);

    /** free(money_string); */
    return 0;
}

===================== Output ===================
Simple, local:                  $1,234.57
International:                  USD1,234.57
parenthesis for negatives:      $1,234.57
fixed width (6 digits):          $  1,234.57
fill character '*':              $**1,234.57
-- note fill characters don't
-- count where the thousdands
-- separator would go:
filling with 9 characters:       $*****1,234.57
Suppress thousands separators:   $****1234.57
================================================

它也是一个POSIX函数 - strfmon() - Jonathan Leffler

0
我认为没有一个C函数可以做到这一点,但你可以自己编写一个。比如说:float price = 23234.45。首先打印带逗号的(int)price,然后打印一个小数点;接着对于小数部分,使用printf("%d", (int)(price*100)%100);即可。

0
int anio, base = 1e4;
double cantidad, rata = 0.5;
int din_buf = 16;
char dinero[din_buf];
printf("%3s%23s\n", "Año", "Cantidad a depositar");

setlocale(LC_ALL, "en_US");

for ( anio = 1; anio < 11; anio++) {
    cantidad = base * pow(rata + 1, anio);
    strfmon(dinero, din_buf, "%#6n", cantidad);
    printf("%3d\t%s\n", anio, dinero);
}

你应该在代码中加入一些解释。像这样的原始代码回答并不是很有帮助。 - Elzaidir

0

Windows用户(使用MSVC)

您不能使用:

您只能使用Win32 API:

示例:

#include <stdio.h>
#include <wchar.h>
#include <windows.h>

int main(void)
{
  double money = 1234567.89;
  wchar_t s[20], money_s[20];
  swprintf( s, sizeof s, L"%.2f", money );
  GetCurrencyFormatEx( L"en_US", 0, s, NULL, money_s, (int)sizeof money_s );
  printf( "You are owed %S!\n", money_s );
}

You are owed $1,234,567.89!

无论何时,如果您使用swprintf()计算货币的精度高于100分之一,请注意四舍五入误差。(如果您欠钱,您可能不想将其四舍五入为更高的金额。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接