如何在cygwin下使用gcc设置std::locale?
我正在尝试编写一个简单的程序来枚举磁盘上的文件,但我陷入了伟大的 UTF 前沿。
我正在使用 boost::recursive_directory_iterator 来枚举文件。这很好用,但 Windows 设置为“加拿大法语”,并且许多文件和目录都有法语字符(如 é、è、ç)。这些文件名未正确显示在屏幕上,我正在使用 wcout。我看到一个“▒”而不是锐角字符。即使 boost::filesystem::ifstream 也无法打开这些文件。
我尝试添加“std::locale::global(std::locale(""))”,但起初只抛出异常。我发现当执行程序时 LANG 设置为“”时,前一个命令不再抛出任何异常,但它只设置“C”语言环境,而不是操作系统使用的语言环境(我希望是“ fr_CA.UTF-8”或“fr_CA.ISO8859-1”)。 LANG 的任何其他值都会使异常恢复...
必须做什么才能让 cygwin gcc 程序在 i18n 世界中可用?
我写这个是为了测试各种区域设置 ID:
#include <iomanip>
#include <iostream>
#include <locale>
using namespace std;
void tryLocale(string ID)
{
try{
cout << "Trying " << std::setw(18) << std::left << "\"" + ID + "\" ";
std::locale Loc(ID.c_str());
cout << "OK (" << Loc.name() << ")" << endl;
}catch(...){
cout << "FAIL" << endl;
}
}
const char *Locales[] = { "", "fr", "fr_CA", "fr_CA.UTF-8", "fr_CA.ISO8859-1", "C", 0};
int main()
{
cout << "Classic = " << std::locale::classic().name() << endl << endl;
int i = 0;
do
{ tryLocale(Locales[i]);
} while(Locales[++i]);
return 0;
}
这给了我这个输出(没有任何 LANG 或 LC_ALL):
Classic = C
Trying "" FAIL
Trying "fr" FAIL
Trying "fr_CA" FAIL
Trying "fr_CA.UTF-8" FAIL
Trying "fr_CA.ISO8859-1" FAIL
将 LANG 设置为“”,第一个“尝试”变成
Trying "" OK (C)
抛出的异常打印:
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid
I'm trying to make a simple program to enumerate the files on my disks, but I'm stuck at the great UTF frontier.
I'm using boost::recursive_directory_iterator to enumerate the files. That's works great, but Windows is set to "french canada" and many files and directories have french characters (likes é, è, ç). These filenames are not displayed correctly on the screen and I'm using wcout. I see a '▒' instead of the acute chars. Even boost::filesystem::ifstream is unable to open these files.
I tried to add "std::locale::global(std::locale(""))", but at first that only thrown an exception. I have found that when LANG is set to "" while executing the program, the previous command does not throw any more, but it only set the "C" locale instead of being the one use by the OS (which I expect to be "fr_CA.UTF-8" or "fr_CA.ISO8859-1"). Any other value for LANG bring the exception back...
What must be done to have a cygwin gcc program usable in an i18n world?
I have write this to test various locale ID:
#include <iomanip>
#include <iostream>
#include <locale>
using namespace std;
void tryLocale(string ID)
{
try{
cout << "Trying " << std::setw(18) << std::left << "\"" + ID + "\" ";
std::locale Loc(ID.c_str());
cout << "OK (" << Loc.name() << ")" << endl;
}catch(...){
cout << "FAIL" << endl;
}
}
const char *Locales[] = { "", "fr", "fr_CA", "fr_CA.UTF-8", "fr_CA.ISO8859-1", "C", 0};
int main()
{
cout << "Classic = " << std::locale::classic().name() << endl << endl;
int i = 0;
do
{ tryLocale(Locales[i]);
} while(Locales[++i]);
return 0;
}
And that gives me this output (without any LANG or LC_ALL):
Classic = C
Trying "" FAIL
Trying "fr" FAIL
Trying "fr_CA" FAIL
Trying "fr_CA.UTF-8" FAIL
Trying "fr_CA.ISO8859-1" FAIL
With LANG set to "", the first "trying" becomes
Trying "" OK (C)
The exception thrown print this:
terminate called after throwing an instance of 'std::runtime_error'
what(): locale::facet::_S_create_c_locale name not valid
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论