我有一个Linux系统设置为某个语言环境并运行c ++应用程序。我可以从c ++应用程序或OS本身(通过更改std::setlocale(LC_NUMERIC, "en_US.UTF-8")
)执行/etc/default/locale
。我没有访问main函数,所以我在我的函数中做std::setlocale(LC_NUMERIC, "en_US.UTF-8")
并且它工作正常。
但是,我想在我的应用程序中对象级别或某个全局级别(一次)执行此操作。我在互联网上看了很多但没有找到太多帮助,所以决定问一下。这是我的GPS位置结构
所以,基本上
//struct Position : std::numpunct<char> {
struct Position {
Position() { isValid = PR_FALSE; lat = 0; lng = 0; elevation = 0; };
PRBool isValid;
double lat;
double lng;
double elevation;
//char do_decimal_point() const { return '.'; } // separate with slash
};
然后,在我的功能中我做
mycheckposition(){
Position checkPosition;
Position mPosition;
// get some data in above.
double distance;
GetDistanceBetweenWGS84Coords(checkPosition, mPosition, distance);
}
我的问题是我应该在哪里有效和安全地进行setlocale。我的位置值得到逗号而不是点,然后GetDistanceBetweenWGS84Coords失败。我系统上的LC_NUMERIC用逗号表示带小数的数字。可能是,如果有人想看GetDistance函数,请点击这里。
int GetDistanceBetweenWGS84Coords(const Position& from, const
Position& to, double& distance)
{
const double EARTH_RADIUS_IN_METERS = 6372797.560856;
const double DEG_TO_RAD = 0.017453292519943295769236907684886;
double latitudeArc = (from.lat - to.lat) * DEG_TO_RAD;
double longitudeArc = (from.lng - to.lng) * DEG_TO_RAD;
double latitudeH = sin(latitudeArc * 0.5);
latitudeH *= latitudeH;
double lontitudeH = sin(longitudeArc * 0.5);
lontitudeH *= lontitudeH;
double tmp = cos(from.lat*DEG_TO_RAD) * cos(to.lat*DEG_TO_RAD);
double arcInRadians = 2.0 * asin(sqrt(latitudeH + tmp*lontitudeH));
distance = EARTH_RADIUS_IN_METERS * arcInRadians;
return 0; //success
}
我确实发现了一些可以解决我的问题,但却没有成功解决问题的方法。不确定this链接中的描述是否跟在std lib之后。
答案 0 :(得分:1)
前段时间我给出了类似问题的答案,并试图澄清语言环境的问题,所以如果你想了解更多:stod does not work correctly with boost::locale。简而言之:
在插件中调用std::setlocale
并不是一件好事,因为它是整个应用程序的全局状态,你可能会弄乱应用程序的其他部分。至少您应该在完成后立即重置区域设置。
如果您使用std::stream
(stringstream
,cin
,cout
),则流的语言环境与全局C ++语言环境的值匹配创建流对象的时刻。通常它是经典的&#34; C&#34;语言环境。但是没有保证,因为应用程序的某些部分可以像你一样操纵它。
您可以通过调用std::stream
确保std::stream::imbue
具有所需的区域设置。这只会操纵您的流而不是全局状态。
例如:
std::stringstream stream;
stream.imbue(std::locale::classic());//classical locale "C" with separator '.'