Windows下wxApp的locale设置
发布者:
pwang
在写完文章Linux下strtod出错与C++国际化问题
有一个新的疑问:strtod和wxApp在Windows下表现如何呢。
查询MSDN得知,VC同样提供了setlocale函数。
char *setlocale(
int category,
const char *locale
);
wchar_t *_wsetlocale(
int category,
const wchar_t *locale
);
category参数:
LC_ALL
所有类别,如下所示。
LC_COLLATE
strcoll 、 _stricoll, wcscoll、_wcsicoll、 strxfrm、 _strncoll、 _strnicoll、_wcsncoll、 _wcsnicoll 和 wcsxfrm 函数。
LC_CTYPE
字符处理函数 (除外 isdigit、isxdigit、mbstowcs和 mbtowc,不受影响)。
LC_MONETARY
localeconv 函数返回货币格式信息。
LC_NUMERIC
对于格式化输出实例 (例如 printf),数据转换实例和通过 localeconv返回的非货币格式信息的十进制点字符。 除十进制点字符之外,还有 LC_NUMERIC 设置通过 localeconv 返回的千位分隔符和分组控件字符串。
LC_TIME
strftime 、 wcsftime 函数。
与glibc的函数声明相比,category参数接受的类型稍微少了一点儿。
下面简要测试下wxApp在Windows下的行为
测试代码如下:
bool App::OnInit ()
{
wxLogDebug("Current code page : %s", setlocale(LC_CTYPE, NULL));
//".ACP" means using the code page which OS uses currently
setlocale(LC_CTYPE, ".ACP");
wxLogDebug("Current code page : %s", setlocale(LC_CTYPE, NULL));
...
}
输出结果是:
现在可知,wxApp在Windows上的locale默认是C,没有使用系统的locale。这与Linux下的行为截然不同。
不得不说,wx库在跨平台开发中真是到处是陷阱。。。
参考MSDN的区域设置名称、语言和国家/地区字符串说明,locale的表述格式如下:
locale :: "locale_name"
| "language[_country_region[.code_page]]"
| ".code_page"
| "C"
| ""
| NULL
所以输出的字符串具体可以解释为:
language: Chinese
country region: Peoples's republic of China
code page: 936
代码936表示 GBK简体中文,1252表示西欧拉丁语系。
另外, Windows下通过setlocale来设置时,locale字符串参数也提供了一定的灵活性。
比如,下面三行代码所表达的意思一致。
snippet_file_name="blog_20140325_4_177866" name="code"}
setlocale( LC_ALL, "en-US" );
setlocale( LC_ALL, "English" );
setlocale( LC_ALL, "English_United States.1252" );
接着测试下Windows下德语是否还有问题
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
void use_strtod()
{
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)
);
char* str = "0.06";
char* end = NULL;
double d = strtod(str, &end);
printf("str=%s, end=%s, %f\n", str, end, d);
}
void change_locale(int cat, const char* str)
{
if (!setlocale(cat, str))
printf("fail to change locale: %s \n", str);
else
printf("success to change locale: %s \n", str);
}
int main(int argc, char* argv[])
{
use_strtod();
setlocale(LC_ALL, ".ACP"); //to avoid using the default "C" locale.
printf("System locale: %s\n", setlocale(LC_ALL, NULL));
//change_locale(LC_ALL, "en-US"); //fail
//change_locale(LC_ALL, "English"); //sucess
change_locale(LC_ALL, "English_United States.1252");
//change_locale(LC_ALL, "de-DE"); //fail
//change_locale(LC_ALL, "German"); //sucess
change_locale(LC_ALL, "German_Germany.1252");
use_strtod();
change_locale(LC_NUMERIC, "C");
use_strtod();
return 0;
}
对这个小程序稍微解释下:
-
程序第8行和11行之所以注释掉,是因为Windows下没有LC_MESSAGES这个参数。
-
line 20: 通过判断setlocale的返回值,可以知道到底当前操作成功没有。
-
main函数先后测试在默认locale、系统locale和德语下strtod的运行情况。
-
line 37:仅仅修改LC_NUMERIC,看看strtod是否能正确工作。
-
line 30和33在某些机子上会失败,所以一定要检测setlocale的返回值。
测试结果是:
这说明Windows 下德语locale也存在同样的问题,同样可以通过修改locale的设置来避免这个问题发生。
那么在不改变locale的情况下能不能实现自定义的数字格式输出呢?
C++提供了相应的类来解决这种需求。C++ locale的用法可以参考 C++manual
测试代码如下:
#include <iomanip>
#include <iostream>
using namespace std;
template <typename T>
struct thousands: std::numpunct <T>
{
public:
thousands() { }
protected:
T do_thousands_sep() const { return '.';}
std::basic_string <T> do_grouping() const { return "\3"; }
T do_decimal_point() const { return ','; }
};
int main()
{
locale loc( locale::classic(), new thousands <char> () );
cin.imbue( loc );
cout.imbue( loc );
//cout << "LC_ALL: " << setlocale(LC_ALL,NULL) << endl;
cout << setprecision(10);
cin >> setprecision(10);
cout << "output number 123456.1 > " << 123456.1 << endl;
double d;
cout << "Enter a number > ";
cin >> d;
cout << "Your input number is " << d << endl;
return 0;
}
测试结果:
output number 123456.1 > 123.456,1
Enter a number > 654.321,123
Your input number is 654.321,123
这个测试程序在Linux同样可以正常运行。
睿初科技软件开发技术博客,转载请注明出处
blog comments powered by Disqus
发布日期
标签
最近发表
- volatile与多线程
- TDD practice in UI: Develop and test GUI independently by mockito
- jemalloc源码解析-核心架构
- jemalloc源码解析-内存管理
- boost::bind源码分析
- 小试QtTest
- 一个gtk下的目录权限问题
- Django学习 - Model
- Code snippets from C & C++ Code Capsule
- Using Eclipse Spy in GUI products based on RCP
文章分类
- cpp 3
- wxwidgets 4
- swt/jface 1
- chrome 3
- memory_management 5
- eclipse 1
- 工具 4
- 项目管理 1
- cpplint 1
- 算法 1
- 编程语言 1
- python 5
- compile 1
- c++ 7
- 工具 c++ 1
- 源码分析 c++ 3
- c++ boost 2
- data structure 1
- wxwidgets c++ 1
- template 1
- boost 1
- wxsocket 1
- wxwidget 2
- java 2
- 源码分析 1
- 网路工具 1
- eclipse插件 1
- django 1
- gtk 1
- 测试 1
- 测试 tdd 1
- multithreading 1