mbstowcs 和ifstream 前为何要setlocale

最近看公司的一些代码,发现一些地方调用了std::locale::global(locale("")); (c++) 和 setlocale(LC_ALL, "");(c)。

如多字节字符转换为宽字符:

setlocale(LC_ALL, "");
const size_t len = byte_size / sizeof(wchar_t);
size_t res = mbstowcs(buf, info, len);

ifstream读取文本:

std::locale::global(locale(""));
std::ifstream in(filePath, std::ios::in);
std::locale::global(locale("C"));

概念:

C/C++程序中,locale(即系统区域设置,即国家或地区设置)将决定程序所使用的当前语言编码、日期格式、数字格式及其它与区域有关的设置,locale设置的正确与否将影响到程序中字符串处理(wchar_t如何输出、strftime()的格式等)。因此,对于每一个程序,都应该慎重处理locale设置。

C locale和C++ locale是独立的。C locale用setlocale(LC_CTYPE, “”)初始化,
C++ locale用std::locale::global(std::locale(“”))初始化。这样就可以根据当前运行环境正确设置locale。

原因:

vs2005中std::fstream打开文件的函数中,传入的const char* 文件名作为多字节首先被mbstowcs 转换成宽字节,然后在转发给Unicode版本的API进行实际的打开文件操作。

对于mbstowcs 函数来说,它需要知道多字节的编码类型才能正确的将其转换为宽字节的Unicode,这个编码类型没有通过函数的参数列表传入,只能依赖全局的locale。全局

的locale默认没有使用系统当前的语言,而是设置为"C" locale。

解决:

在调用mbstowcs 或使用它的函数前,先用setlocale将全局默认locale设置为当前系统的locale:

setlocale(LC_ALL, "");

如果是非中文系统上转GBK编码,就需要指定中文locale:

setlocale(LC_ALL, "chs");

猜你喜欢

转载自www.cnblogs.com/wangkk/p/10154896.html