ironicaldiction
ironicaldiction

Reputation: 1207

How can I format currency with commas in C?

I'm looking to format a Long Float as currency in C. I would like to place a dollar sign at the beginning, commas iterating every third digit before decimal, and a dot immediately before decimal. So far, I have been printing numbers like so:

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

which returns something like

You are owed $123456789.00!

Numbers should look like this

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

Any answers need not be in actual code. You don't have to spoon feed. If there are C-related specifics which would be of help, please mention. Else pseudo-code is fine.

Upvotes: 5

Views: 30255

Answers (5)

Dúthomhas
Dúthomhas

Reputation: 10048

Windows users (with MSVC)

You cannot use:

You are kind of stuck using the Win32 API:

Example:

#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!

As always, watch your rounding errors with swprintf() if you are counting currency with more precision than 100ths. (You may not want to round up if you owe money.)

Upvotes: 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);
}

Upvotes: 0

rreagan3
rreagan3

Reputation: 127

I know this is a way-old post, but I disappeared down the man rabbit hole today, so I thought I'd document my travels:

There's a function called strfmon() that you can include with monetary.h that will do this, and do it according to local or international standards.

Note that it works like printf(), and will take as many double arguments as there are % formats specified in the string.

There's a lot more to it than what I have here, and I found this page to be the most helpful: https://www.gnu.org/software/libc/manual/html_node/Formatting-Numbers.html

#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
================================================

Upvotes: 3

Carl Norum
Carl Norum

Reputation: 224924

Your printf might already be able to do that by itself with the ' flag. You probably need to set your locale, though. Here's an example from my machine:

#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;
}

And running it:

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

This program works the way you want it to both on my Mac (10.6.8) and on a Linux machine (Ubuntu 10.10) I just tried.

Upvotes: 11

tweaksp
tweaksp

Reputation: 621

I don't think there's a C function to do that, but you could just write your own? Say float price = 23234.45. First print (int)price with commas, print a decimal point; then for the decimal part, do printf("%d", (int)(price*100)%100);

Upvotes: 0

Related Questions