Convert "dot" in "comma" C++.

Hello guys, i'm from Brazil, i was making a Calculator Console Application with C++, but in Brazil we use "comma" not "dot" on decimal numbers:
Ex: en_US = 3.14 / pt_BR = 3,14.

My actual code is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <locale.h>

using namespace std;

int main (){

    setlocale(LC_ALL,"");
    setlocale(LC_NUMERIC,"");

    cout << "WELCOME TO CONSOLE CALCULATOR!" << endl << endl;

    cout << "Type a first value: " << endl;
    double firstValue;
    cin >> firstValue;

//verify if first value is a valid number
while (!cin) {
        cout << "\nType a valid number: " ;
        cin.clear();
        cin.ignore(256,'\n');
        cin >> firstValue;
    }
    //get second value
    //do the operation
    //return a result
    return 0;
}


When I type 3.14 in console, it accept, but in brazil when I type 3,14 just bug it. As you can see, i used "locale" library and it works with strings "ã, é, ó" used here in brazil, but not work on numbers my question is:

How do to Console accept "comma" as "dot", or convert it?


*i'm a begginer, sorry for my bad english.
*i use Sublime Text 3 and MinGW Compiler.
Last edited on
you could (i guess) read the number in as a string, then use replace:
http://www.cplusplus.com/reference/string/string/replace/
to change the comma to a decimal point, and then use atoi:
http://en.cppreference.com/w/cpp/string/byte/atoi

to convert it to a double, and then carry on as normal.
Last edited on
setlocale sets C locale. It has no effect on C++ streams.

You need to set C++ locale:
1
2
3
4
5
6
7
8
9
#include <locale> //C++ locale header

//...
//Handles streams and other locale-dependant things created after this line.
std::locale::global std::locale( "" ));

//Imbues standard input and output with enviroment locale (one your system uses)
std::cin.imbue(std::locale( "" ));
std::cout.imbue(std::locale( "" ))


Edit: I just noticed that you are using MinGW. In this case proper solution will not work (as standard library implementation used by MinGW has absymal locale support).

Use workaround:
1
2
3
4
5
6
7
8
9
10
11
12
13
#include<iostream>
#include<locale>

struct comma_separator : std::numpunct<char> {
    virtual char do_decimal_point() const override { return ','; }
};

int main()
{
    double d = 3.145;
    std::cout.imbue(std::locale(std::cout.getloc(), new comma_separator));
    std::cout << d;
}
3,145
Last edited on
@MiiNipa

Your answer works, but not im my project, because i'm using using namespace std; i tried write without "std::" but not work, can you do this for me?

Or just explain what this code you do, means.

Thanks!
Even you have using namespace std; somewhere, qualified names (with std) should still work. You can remove std:: in all places and it still should work (unless you have name clash brought by using namespace).

What does not work? Any errors?

Code is simple: on lines 4-6 I create new class, inheriting from standard numpunct class, containing different number punctuation rules (decimal and group separator, amount of digits in group, names for boolean values, etc.) and override cirtual function returning decimal separator, making it return comma.
Then I get current output locale (std::cout.getloc()) and construct a copy of it with numeric punctuation facet replaced with my own:
1
2
3
//  Copy old locale↓
std::locale(std::cout.getloc(), new comma_separator)
//                                 ↑ Replace numeric punctuation facet 
Then I imbue output stream with new locale: std::cout.imbue(/*Freshly created locale*/);
@MiiNiPaa

Like I sad, your code works, fine for "cout", but was i wondering is convert when user type "3,14" the console consider the "," like a "." then to be able to de a operation in calculator. Because in console when type "," just bug it.

The problem is "cin" not "cout", anyway, i think C++ Console is limited in question of countries and regions formacts.

So, thanks man for your big help.
The problem is "cin" not "cout", anyway well, imbue another stream then:
1
2
//   ↓↓↓
std::cin.imbue(std::locale(std::cout.getloc(), new comma_separator));


i think C++ Console is limited in question of countries and regions formacts.
It is MinGW standard library (libstdc++) windows port problem. I suggest to use library from Microsoft compiler bundled with Visual Studio if you want to use locales on Windows.

Edit: or use boost::locale
Last edited on
Topic archived. No new replies allowed.