vs2005 std::locale 的问题


连续碰到两次和locale相关的问题,一次是ifstream, 一次是boost::format, 做了些实验记录下来:

1. ifstream 的文件名参数其实可以接受char *, 也可以接受wchar_t * 作为参数,如果接受char * 的话,实际上内部也是转换成为wchar_t *,但转换的时候问题就来了,如果此文件名里面有汉字,vc2005就转换不对,这样就打不开文件了。在vc2005中,一开始程序的缺省locale 是”C”, 也就是std::locale::classic()返回的,但这个locale下,汉字转换是不正确的,所以,要先用 std::locale::global(std::locale(”"))这

样的语句将locale设到系统缺省的。实际上std::locale:: global(std::locale(”.936″)) 也是一样的。936就是简体中文的codepage(代码页)。 此时用 locale.name() 打印出来的locale名称为: “Chinese_People’s Republic of China.936″

2. 但是一旦locale变为936了,cout 输出中文就又会有问题,碰到中文就会断掉,而且后面的东西再也显示不出来。这可以通过在ifstream打开文件之后,用std::locale:: global(std::locale(”C”))再设回缺省locale来解决。注:这个我没遇到,中文正常显示。

3. locale设为936的另一个问题是,boost::format 中 如果输出数字的话,1234会变成1, 234. 这个问题也可以用上面的方法来解决。另外一个方法是可以用format的第二个参数来做,例如std::locale::classic() 或者std::locale(”C”);

4. 网上说流输出时候也会将1234变为 1,234,但我直接实验cout << 1234 好像没有问题。看到说碰到这种情况,需要用a.imbue(std::locale(”C”))。注:这个我也没遇到,1234正常显示。

5. 如果ifstream直接用wchar_t *的文件名参数,就很简单了,不更改locale就可以打开文件,后面的cout输出汉字也没有问题,boost::format也没有问题。所以竭力推荐这种方法 

6在使用ifstream之前加一句:setlocale(LC_ALL,""),就可以让ifstream的文件名参数允许有汉字。只要在某处设置一下,就在整个工程中都起作用。



实际操作中使用该方法解决的一个问题:


在使用TRACE 输出LOG信息时,

class subObject
{

public:
	subObject()
	{
		TRACE(L"subObject()");
	};
	~subObject()
	{
		TRACE(L"析构subObject()");
	};
};
以上代码在VS2005中, 析构时会输出错误:

_CrtDbgReport: String too long or IO Error

按照  http://www.cnblogs.com/BeyondTechnology/archive/2011/01/09/1931533.html的方法 

 解决该问题

#include "locale.h"

BOOL CDlgApp::InitInstance()
{

	setlocale(LC_ALL,"chs");
	//CAboutDlg aboutDlg;

	MainObject *pM = new MainObject;
	//aboutDlg.DoModal();
	delete pM;
	return TRUE;
}

LOG 正常输出>>>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值