Почему функция towlower () не преобразует Я в нижний регистр я?

функции towlower() не работает в Visual Studio 2012. Вот пример:

#include <string>
#include <iostream>
#include <io.h>
#include <fcntl.h>
#include <wctype.h>

using namespace std;

int main()
{
    _setmode(_fileno(stdout), _O_U8TEXT);
    wcout << (wchar_t)towlower(L'Я') << endl;
    system("pause");
    return 0;
}

персонаж остается в верхнем регистре. Подобные вопросы задавались здесь раньше, но я не могу найти никаких решений.

есть ли другой метод, который я могу использовать для изменения в нижнем регистре?

3 ответов


использовать локали версия tolower, но не забудьте также установить локаль c.

например:

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

int main()
{
    std::setlocale(LC_CTYPE, "");
    std::wcout << L"The letter is: " << L'Я' << L" => "
               << std::tolower(L'Я', std::locale("")) << std::endl;
}

печатается:

The letter is: Я => я

использование локалей в iostreams-сложный бизнес, и за этим скрывается целый ящик Пандоры. Например, вы можете охотник потоки с локалем, и вы можете управлять несколькими локалями одновременно, и, в частности, вы можете иметь один на поток (что может быть необходимо для строки с состоянием преобразование кодирования)... кто-то должен написать книгу об этом (или вместо этого использовать импульс.Место действия.)


Я вижу две возможности. Первый-locale не устанавливается правильно. От MSDN:

преобразование делу towlower зависит от локали. Только символы, относящиеся к текущему язык меняется в случае. Функции без _l суффикс используйте текущую локаль.

второй-это кодировка исходного файла. L'Я' может означать разные вещи, основываясь на том, что ваш исходный файл закодирован с. Это не будет работать, например, если у вас есть это в UTF-8. Убедитесь, что у вас есть это в UTF-16. Или, чтобы устранить любую возможную путаницу, поставьте ее так '\u042F'

обновление: по второй мысли это все L бизнес-это сложно. Если компилятор правильно понимает кодировку, например, через BOM, это может быть хорошо с UTF-8 или любая другая кодировка. Важно, чтобы он знал, что такое кодировка. Это должно быть очень много реализации специфический.

другие новости: чтобы устранить проблему, попробуйте установить locale через:

_wsetlocale(LC_ALL, L"ru-RU");

или используйте версию, которая принимает локаль в качестве параметра (_towlower_l).

и есть также на вершине всего ПРАГМА это говорит компилятору, как обрабатывать строковые литералы, отличные от ASCII, в файле.


делает ли он меньше повреждений, чем towhigher? j / k. Я не знаком с обратным R, но я знаю, что если символ не имеет эквивалента нижнего регистра, то(w)lower вернет исходный символ. http://en.cppreference.com/w/c/string/wide/towlower