Today I encounter a problem with my C++ code. I try to convert string to double. Then I realize in my computer std::atof doesn’t work properly. Also others(stof stod) doesn’t not work correctly.
Then I decide to find the issue. I write to simple script to print all output of those functions.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// #include <iostream> #include <stdlib.h> int main(int argc, char *argv[]) { std::string num = "3.5"; std::cout<<num<<std::endl; double ret = std::atof(num.c_str()); std::cout<<ret<<std::endl; std::cout<<ret+0.1<<std::endl; ret = std::stof(num); std::cout<<ret<<std::endl; std::cout<<ret+0.1<<std::endl; ret = std::stod(num); std::cout<<ret<<std::endl; std::cout<<ret+0.1<<std::endl; return 0; } |
Outputs:
1 2 3 4 5 6 7 8 |
// 3.5 3 3.1 3 3.1 3 3.1 |
Outputs don’t correct. But all three functions return double. So it is not relating to casting.
While I am trying to give different input. I just try 3,5 instead of 3.5 as a string. Then it works. Because currently, I am in Turkey. The local floating point separator is a comma in Turkey. But when I print double values in std::cout, It prints with dot. So these function use local seperator but printing functions don’t use it. So I try to find, how I can set local settings without changing anything in OS. So I found locale.h header.
This header provides functions that you can set local settings like date, currency symbol, etc.
you can change entire locale setting with using setlocale function.
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 |
// #include <iostream> #include <stdlib.h> #include <locale.h> int main(int argc, char *argv[]) { setlocale (LC_ALL,"en_US.utf8"); std::string num = "3.5"; std::cout<<num<<std::endl; double ret = std::atof(num.c_str()); std::cout<<ret<<std::endl; std::cout<<ret+0.1<<std::endl; ret = std::stof(num); std::cout<<ret<<std::endl; std::cout<<ret+0.1<<std::endl; ret = std::stod(num); std::cout<<ret<<std::endl; std::cout<<ret+0.1<<std::endl; return 0; } |
Outputs:
1 2 3 4 5 6 7 8 |
// 3.5 3.5 3.6 3.5 3.6 3.5 3.6 |