Как я могу использовать std :: imbue, чтобы установить локаль для std :: wcout?
Я пытаюсь использоватьstd::locale
механизм в C ++ 11 для подсчета слов на разных языках. Конкретно у меня естьstd::wstringstream
который содержит название известного русского романа («Преступление и наказание» на английском языке). Что я хочу сделать, это использовать соответствующую локаль (ru_RU.utf8
на моем компьютере с Linux), чтобы прочитать поток строк, посчитать слова и распечатать результаты. Я также должен отметить, что моя система настроена на использованиеen_US.utf8
локали.
Желаемый результат таков:
0: "Преступление"
1: "и"
2: "наказание"
I counted 3 words.
and the last word was "наказание"
Это все работает, когда я устанавливаю глобальную локаль, но не когда я пытаюсьimbue
wcout
поток. Когда я пытаюсь это сделать, я получаю такой результат:
0: "????????????"
1: "?"
2: "?????????"
I counted 3 words.
and the last word was "?????????"
Кроме того, когда я пытаюсь использовать решение, предложенное в комментариях, (которое можно активировать, изменив#define USE_CODECVT 0
в#define USE_CODECVT 1
) Я получаю ошибку, упомянутую вэтот другой вопрос.
Те, кто заинтересован в экспериментировании с кодом, с настройками компилятора или с обоимиэтот живой код.
Мои вопросыПочему это не работает? Это потому чтоwcout
уже открыт?Есть ли способ использоватьimbue
вместо того, чтобы устанавливать глобальную локаль, чтобы делать то, что я хочу?Если это имеет значение, я использую g ++ 4.8.3. Полный код показан ниже.
getwords.cpp#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <locale>
#define USE_CODECVT 0
#define USE_IMBUE 1
#if USE_CODECVT
#include <codecvt>
#endif
using namespace std;
int main()
{
#if USE_CODECVT
locale ru("ru_RU.utf8",
new codecvt_utf8<wchar_t, 0x10ffff, consume_header>{});
#else
locale ru("ru_RU.utf8");
#endif
#if USE_IMBUE
wcout.imbue(ru);
#else
locale::global(ru);
#endif
wstringstream in{L"Преступление и наказание"};
in.imbue(ru);
wstring word;
unsigned wordcount = 0;
while (in >> word) {
wcout << wordcount << ": \"" << word << "\"\n";
++wordcount;
}
wcout << "\nI counted " << wordcount << " words.\n"
<< "and the last word was \"" << word << "\"\n";
}