先放结果
1 setlocale(LC_ALL, ""); 2 rapidxml::file<> f(szPath); 3 setlocale(LC_ALL, "C");
对于setlocale函数,一下是msdn的说法
char *setlocale( int category, const char *locale );
参数
category
受区域设置影响的分类。
locale
区域设置说明符。
如果提供了有效的 locale
和 category
,则返回指向与指定的 locale
和 category
关联的字符串的指针。 如果 locale
或 category
无效,则返回空指针,并且不更改程序的当前区域设置。
例如,调用
setlocale( LC_ALL, "en-US" );
设置所有类别,只返回该字符串
en-US
你可以复制由 setlocale
返回的字符串以还原程序的区域设置信息的该部分。 全局或线程本地存储用于由 setlocale
返回的字符串。 稍后调用setlocale
将覆盖字符串,这将使之前调用返回的字符串指针无效。
如果 locale
指向一个空字符串,即
setlocale(LC_ALL, "");
则区域设置是实现定义的本机环境。 C
的值为 C 转换指定最小的符合 ANSI 标准的环境。 C
区域设置假设所有 char
数据类型为 1 字节,并且其值始终小于 256。
为什么一定要调用setlocale呢?
因为在C/C++语言标准中定义了其运行时的字符集环境为"C",也就是ASCII字符集的一个子集,那么mbstowcs在工作时会将cstr中所包含的字符串看作是ASCII编码的字符,而不认为是一个包含有chs编码的字符串,所以他会将每一个中文拆成2个ASCII编码进行转换,这样得到的结果就是会形成4个wchar_t的字符组成的串,那么如何才能够让mbstowcs正常工作呢?在调用mbstowcs进行转换之间必须明确的告诉mbstowcs目前cstr串中包含的是chs编码的字符串,通过setlocale( LC_ALL, "chs" )函数调用来完成,需要注意的是这个函数会改变整个应用程序的字符集编码方式,必须要通过重新调用setlocale( LC_ALL, "C" )函数来还原,这样就可以保证mbstowcs在转换时将cstr中的串看作是中文串,并且转换成为2个wchar_t字符,而不是4个。 经过转换后的路径当然在实际并不存在,因为这个原因才导致的rapidxml跑出了一个RUNTIME ERROR
记得调用
setlocale(LC_ALL, ""); 后要在合适的地方通过setlocale( LC_ALL, "C" )转换回原本字符集,不然可能会导致其他错误