VC++ STL中的locale问题(2)

原文发表于:http://www.hellocpp.net/Articles/Article/722.aspx

 

其实对我来说 ,这篇文章里要说的问题早就碰到过了。今天只是心血来潮,详细归纳一下。

bug描述:在中文日文系统上创建一个中文日文名字的用户名,在这个用户的目录下创建文件失败。
经过检查,发现只要文件名里带中文或者日文等非英文字符,用fstream创建文件就失败。这个问题第一次用vc2005其实我就碰到过了。
当初的解决方法无非是几个:
1. 在程序启动的时候调用setlocale(LC_ALL,"");
2. 不用fstream,改用fopen
3. 在用fstream的时候,用 wchar_t* 做参数。

那么为什么会产生这个问题呢?原因是CRT中的默认locale在vc++2005/2008下是"C",不是系统默认的,而且,新的STL现在都会把你的char*的文件名参数转化成wchar_t*,这个动作将会使用CRT的locale,所以你传递给vc++的文件名中如果带有中文字符并且用C的locale来转换的话,必然会出现乱码。 那么以上的方法就很容易解释了。
1. setlocale(LC_ALL,"")会让CRT使用系统默认的locale,如果你是用Windows XP/Vista/Win7的话,这个应该就是 区域语言选项里的 位置和 非unicode程序位置。那么自然转换就能正确了。
2. fopen即使内部也是通过win32 API的CreateFile来转化,也会使用系统的locale跟CRT的无关。
3. 你自己都转好了当然没有问题了。

总结一下。其实个人感觉方法3才是王道,你所有的东西都用unicode才是最完美的。

当然问题并不到此为止。
在有些locale下,有些很细小的区别,比如:德文系统下,小数是用 0,1来表示的,而不是常见的0.1. 那么如果你的配置文件里写的是0.1。你调用setlocale(LC_ALL,"")后,在德文系统下,你的0.1用sscanf读出来的将会是错误的值:0.0f。是不是感到很晕眩,呵呵,也许问题还不只这些。 一般Locale包含很多选项,比如LC_CTYPE,LC_NUMERIC LC_CURRENCY,等等。LC_NUMERIC就是影响这个数字的表达形式的。

因此,如果你只是想让C++ STL能正常打开非英文字符的文件名,那么你只需要 setlocale(LC_CTYPE,"")就可以了。

 

目前只总结到这里,有其他发现以后再补充,有不对的地方也欢迎大家提出来。

 

补充:关于使用setlocale设置后,cout不能输出问题,由于我从来不是用cout输出(我一般采用printf打印到控制台+OutputDebugString输出到调试窗口的log模式)。所以本文没有提到。 如果关心这块,可以在打开文件前设置locale,打开文件结束后设置会默认locale:
locale lc = setlocale(LC_ALL , "");

fstream f(".....");

setlocale(LC_ALL , lc);

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值