First note. Please do not use C-Style strings. In C++ we use std::string
. Anyway, also C-style strings will do and can be converted automatically.
Then, for newbies it is the best to transform the input monetary-string to a number-string with just one decimal digit and then use function stold
for conversion. You may read here about it.
But in the real C++ world, you would do 2 things:
- use dedicated C++ facilities
- use localization
Unfortunately this is a rather complex topic and you need a while to understand.
You need to read about the localization library. Here you will learn about 2 major concepts:
- locales
- facets
In general textual representation of dates, monetary values or number formats are governed by regional or cultural conventions. All this properties are contained in a std::locale
object.
But the std::locale
does not offer much functionality. The real localization facilities are offered in the form of facets. And a std::locale
encapsulates several facets. And one of them is about the monetary formatting.
You really can do many things with that and in the end get fully customized behaviour. But, as said, not that easy to understand.
I will use the std::money_get class in my below example.
Please note. This will convert your number into units, without a fraction. In financial calculations we basically should not use fractions, because double
or even long double
cannot store all "reaal" values". Please read about this as well.
Anyway. I will show you an example how such a monetary value would be converted in C++. You maybe shocked by the complexity, but flexibility has its price . . .
Please see:
#include <iostream>
#include <iomanip>
#include <limits>
#include <string>
#include <locale>
#include <sstream>
int main() {
// Input String
char valueAsCString[] = "$567,789,675.89";
// Put it in an istringstream for formatted extraction
std::istringstream iss{ valueAsCString };
// Assume US currency format (On Posix machines, please use "en-US") and set it for the stream
std::locale myLocale("en_US");
iss.imbue(myLocale);
// Assume that everthing is good
std::ios_base::iostate ioError{ std::ios_base::goodbit };
// Here we will get the value in UNITS, so without a fraction!!!
long double value{};
// Parse the money string and get the result
std::use_facet<std::money_get<char>>(myLocale).get(std::istreambuf_iterator<char>(iss), {}, false, iss, ioError, value);
// Check Error state
iss.setstate(ioError);
if (iss)
// Show result
std::cout << std::setprecision(std::numeric_limits<long double>::digits10 + 1) << std::setw(25) << value / 100 << '\n';
else
std::cerr << "\nError during conversion\n";
}