wcout函数无法打印法语字符。

5

我使用wcin来将单个字符存储在wchar_t中。然后我尝试用wcout调用打印它和法语字符'é':但是我看不到控制台上的字符。

我的编译器是g++ 4.5.4,操作系统是Ubuntu 12.10 64位。

这是我的尝试(wideChars.cpp):

#include <iostream>

int main(){
    using namespace std;

    wchar_t aChar;
    cout << "Enter your char : ";
    wcin >> aChar;
    wcout << L"You entered " << aChar << L" .\n";

    return 0;
}

当我启动程序时:
$ ./wideChars 
Enter your char : é
You entered  .

那么,这段代码有什么问题吗?

1
你的终端设置为什么编码? - filmor
你好,我该如何检查这个?谢谢 - loloof64
我撤回我的答案。我在自己的Xubuntu安装上检查了一下,发现了同样的问题。由于某种原因,“wcin”拒绝读取“é”字符,并设置了失败位。 - wilx
我认为这是编译器的问题:因为我用wcout <<“输入您的字符(如é)”替换了第7行,但我仍然无法在提示中看到字母'é'。 - loloof64
1个回答

3
首先,添加一些错误检查。测试输入后wcin.good()返回什么,以及“您输入”的打印后wcout.good()返回什么?我怀疑其中一个会返回false
您的LANGLC_*环境变量设置为什么? 然后尝试通过在main()顶部添加以下内容来修复此问题:wcin.imbue(std::locale("")); wcout.imbue(std::locale("")); 我现在没有我的Ubuntu,所以我在这里是盲目飞行并且主要是猜测。 更新 如果上述建议没有帮助,则尝试像这样构造语言环境,并使用imbue()应用该语言环境。
std::locale loc (
    std::locale (),
    new std::codecvt_byname<wchar_t, char, std::mbstate_t>("")));

更新2

以下方法适用于我。重要的是同时设置C语言环境。个人认为,这是GNU C++标准库实现中的一个bug。除非我错了,否则设置std::locale::global("");也应该设置C库环境。

#include <iostream>
#include <locale>
#include <clocale>

#define DUMP(x) do { std::wcerr << #x ": " << x << "\n"; } while (0)

int main(){
    using namespace std;

    std::locale loc ("");
    std::locale::global (loc);
    DUMP(std::setlocale(LC_ALL, NULL));
    DUMP(std::setlocale(LC_ALL, ""));    
    wcin.imbue (loc);

    DUMP (wcin.good());
    wchar_t aChar = 0;
    wcin >> aChar;
    DUMP (wcin.good());
    DUMP ((int)aChar);
    wcout << L"You entered " << aChar << L" .\n";

    return 0;
}

更新3

我有些困惑,现在我无法再次重现它,并且设置 std::locale::global(loc); 似乎也对 C 语言环境做了正确的事情。


感谢您的回答:在输入后,wcin.good()返回0(即false),在最后一个输出之后:wout.good()返回1(即true)。我的LANG环境变量设置为fr_FR.UTF-8,并且“echo $ LC _ *”给出了“escapeChars escapeChars.cpp limits limits.cpp wideChars wideChars.cpp”。现在我将尝试您的下一个解决方案。我的源文件和可执行文件是wideChars.cpp和wideChars。 - loloof64
很遗憾,你提供的解决方案都没有帮到我。即使我使用了“loc(locale, new codecvt_bytename)”来创建本地化对象。我也已经包含了本地化定义,并在main()函数中保留了指令“using namespace std”。这是我最新的源文件:http://pastebin.com/ir56SKP0 - loloof64
@LaurentBERNABE:我已经更新了回答,并提供了一个可行的示例。 - wilx
你是对的,设置C++区域设置应该也会设置C区域设置(至少只要您指定的C++区域设置有名称;否则,关于C区域设置的行为是实现定义的)。当然,反过来不起作用。设置C区域设置对C++区域设置没有影响。如果这是GNU中的一个错误,可能值得提出申诉。 - Cody Gray
@wilx 非常感谢。那解决了我的问题。但是,我没有成功解决与wcout相关的问题(尽管我已经调用了wcout.imbue(loc)):输入到给定wcout字符串中的' é '没有被打印出来。无论如何,这应该是另一个话题。 - loloof64

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接