【发布时间】:2016-02-03 15:15:58
【问题描述】:
我有一个设置为某些语言环境的 Linux 系统,它正在运行一个 c++ 应用程序。我可以从 c++ 应用程序或操作系统本身(通过更改 /etc/default/locale)执行 std::setlocale(LC_NUMERIC, "en_US.UTF-8")。我无法访问主要功能,所以我在我的功能中做了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 链接中的描述是否遵循标准库。
【问题讨论】:
-
有什么问题?您正在编写一个插件并且它多次调用
setlocale?加载插件时没有应用程序调用的设置挂钩吗?如果没有,只需使用bool全局以避免第二次调用它。但是,更改应用程序的语言环境对于插件来说可能不是很好的行为,因此您可能需要考虑避免对语言环境的依赖,或者使用本地化 API,例如strtol_l。 -
@Potatoswatter
strtol_l看起来很有用。有什么我可以研究的例子吗?或者它是strtol。此外,我的插件有一个 init 函数,但我在那里做了 setlocale 但它没有效果。就我而言,setlocale 仅在我按上述方式执行或在操作系统中设置 LC_NUMERIC 时才有效。 -
我用以下方法解决了这个问题:
std::istringstream istrLat(NS_ConvertUTF16toUTF8(value).get()); istrLat >> checkPosition.lat;我从here 得到了提示。这里重要的是std::istringstream,正如链接正确显示的那样,原因是“标准 iostreams 默认使用全局语言环境(反过来应该初始化为经典(美国)语言环境)。"