- 问题
最近,公司的GUI程序(基于wxWidgets)在Linux下出来一个bug,说起来有点不可思议。
类似下面的一块代码
const char* str="0.06"; char* end=NULL; double d = strtod(str, &end); printf("str=%s, end=%s, %f\n", str, end, d);
输出结果是:
str=0.06, end=.06, 0,000000
难道strtod会出错了吗?不可能吧?!
为了确认这个问题,写一个小程序在客户机子上测试。
test 1:
// main.cpp
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
const char* str="0.06";
char* end=NULL;
double d = strtod(str, &end);
printf("str=%s, end=%s, %f\n", str, end, d);
return 0;
}
编译并运行这个测试程序, 发现结果完全正常。说明GUI程序本身存在某种问题。
后来客户怀疑可能与locale设置相关,就更改了locale设置。客户的机子默认是德语,改成环境变量LC_ALL=C后,GUI程序能够正常运行了!
strtod在德语环境下会出错?!!
- 重现bug
简单修改测试程序 main.cpp,得到
test 2
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
int main(int argc, char* argv[])
{
printf("LC_ALL:%s\n"
"LC_CTYPE:%s\n"
"LC_MESSAGES:%s\n"
,setlocale(LC_ALL, NULL)
,setlocale(LC_CTYPE, NULL)
,setlocale(LC_MESSAGES, NULL)
);
const char* str="0.06";
char* end=NULL;
double d = strtod(str, &end);
printf("str=%s, end=%s, %f\n", str, end, d);
return 0;
}
为了模拟客户的环境,设置当前的LANG为德语:
export LANG=de_DE.UTF-8
运行程序,输出结果是:
LC_ALL:C
LC_CTYPE:C
LC_MESSAGES:C
str=0.06, end=, 0,06
这说明test 1 和test 2在进入main函数的时候,程序自身的locale是C。
bool App::OnInit ()
{
wxLogDebug("Current locale : %s", setlocale(LC_ALL, NULL));
结果发现wx程序的默认locale是
de_DE.UTF-8, 也就是系统的locale设置。
查看gtk中gtk_set_locale的manual
gchar* gtk_set_locale (void);
Initializes internationalization support for GTK+. gtk_init()
automatically does this, so there is typically no point in calling this function.
If you are calling this function because you changed the locale after GTK+ is was initialized, then calling this function may help a bit. (Note, however, that changing the locale after GTK+ is initialized may produce inconsistent results and is not really supported.)
In detail - sets the current locale according to the program environment. This is the same as calling the C library function setlocale (LC_ALL, "")
but also takes care of the loc