DEAR PEOPLE FROM THE FUTURE: Here's what we've figured out so far...

Welcome! This is a Q&A website for computer programmers and users alike, focused on helping fellow programmers and users. Read more

What are you stuck on? Ask a question and hopefully somebody will be able to help you out!
+4 votes

I need a C function that takes a double and returns US$. It needs to work for either C89 and/or C99.

For example, someone or some thing types 3000 and it goes into the double. I need the function for printing out to another process that only cares about strings. So in this case, it should look like "$3,000.00".

I figure I might be able to use something in the family of sprint/printf, but I thought I'd ask around.

by
+3

As a side note, you should use integers for money and not doubles (sources: 1, 2)

0

I absolutely agree. I avoid using floats and the like at all costs. In this particular case, it's a library that I only directly have access to the header files, so I'm wrapping it with another module first (whenever I get back to it, and I appreciate the extra brain cycles from everyone).

1 Answer

+3 votes
 
Best answer

You could use strfmon(3) - convert monetary value to a string:

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

...

// Set the locale (https://www.gnu.org/software/libc/manual/html_node/Setting-the-Locale.html)
if (setlocale(LC_MONETARY, "en_US.utf8") == NULL) {
    puts("Cannot set locale.");
    return -1;
}

double money = 3000;
char buffer[100];
ssize_t buffer_length = strfmon(buffer, sizeof(buffer), "%.2n", money);
if (buffer_length < 0)
    printf("Cannot convert");
else
    printf("%s", buffer);
by
selected by
+1

That's a great idea to use monetary.h for LC_MONETARY.

+2

For posterity, I did the following, though main is made up for simplicity.

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


#define BUFFER_SIZE 100


void get_my_money_string(char **ptr, double money, int buf_size)
{
  char buffer[buf_size];
  if (strfmon(buffer, sizeof(buffer), "%.2n", money) < 0)
    return;

  *ptr = malloc(buf_size);
  strcpy(*ptr, buffer);
}


double get_amount(char *ptr)
{
  char *buffer;
  double result;
  result = strtod(ptr, &buffer);
  return result;
}


int main(int argc, char *argv[])
{
  if (argc < 2) {
    puts("Must supply only 1 value.");
    return -3;
  }
  if (argc > 2) {
    puts("Must supply only 1 value.");
    return -2;
  }
  if (setlocale(LC_MONETARY, "en_US.utf8") == NULL) {
    puts("Cannot set locale.");
    return -1;
  }

  double money;
  char *well_formed_money;

  money = get_amount(argv[1]);
  get_my_money_string(&well_formed_money, money, BUFFER_SIZE);
  printf("Result: %s\n", well_formed_money);

  return 0;
}
Contributions licensed under CC0
...