LINUX.ORG.RU

C++ tolower для русского языка.

 , , ,


0

1

Добрый день. Пишу на C++ только под линукс с использованием буста. Не буст tolower, не std не переводят тот же std::string h = «ПривЕт» в привет. Есть , может быть, какие то стандартные линуксовые фичи? P.S. желательно что бы можно было потом и с другими языками работать, не затачивать только под русский.

Код показывай.

FIL ★★★★
()

Есть версия tolower со вторым параметром - локалью, а еще можно взять towlower для wchar. А еще есть ICU.

anonymous
()

AFAIK std::string не очень подходит для многобайтовых символов, например, для utf8.

Kroz ★★★★★
()
Sentence::Sentence(std::string sntc)
	{       
        orSentence = sntc;
        std::vector<std::string> orWords;
        std::vector<std::string> words;
        boost::split(words, orSentence, boost::is_any_of("\t "));
        //this->words = words;
        for(std::string word : words)
        {

            boost::algorithm::trim(word);
            boost::algorithm::to_lower(word);
            /*//Delete from word \r
            if (!word.empty() && word[word.size() - 1] == '\r')
                word.erase(word.size() - 1);*/
            FoundWord foundWord ;
            foundWord = Vocabulary::GetWord(word);
            if(foundWord.isFound == false)
                continue;
            else
                orWords.push_back (foundWord.word.originalWord);
        }
		
	}

Ну если так хочется. Это класс предложения , фигурирует только русский текст. Смотрю через дебаггер на происходящее. где trim - все отлично, убирает \r и пробелы, дальше , после to_lower без изменений.

Про ICU много видел, пока искал решение, но неужели нет стандартного способа :)

Warezovvv
() автор топика
Ответ на: комментарий от Warezovvv

Стандартного нет. В стандартной библиотеке поддержка юникода практически никакая (разве что сами кодировки поддерживаются), остаются сторонние библиотеки.

asaw ★★★★★
()
Ответ на: комментарий от Warezovvv

Не знаю, я рекомендую Qt: http://doc.qt.io/qt-5/qlocale.html#toLower Это самый легкий способ. Если она правильно собрана (возможно, потребуется собрать её с ICU), то всё работает как часы.

asaw ★★★★★
()
Последнее исправление: asaw (всего исправлений: 1)
Ответ на: комментарий от asaw

Хаха, хотел дописать (но не стал). «может Qt взять, что бы зависимости не плодить». Ладно, спасибо :)

Warezovvv
() автор топика
#include<iostream>
#include<iomanip> // std::endl
#include<string>
#include<algorithm> // transform

int main()
{
        std::locale::global(std::locale("en_US.utf8"));
        std::wcout.imbue(std::locale());

        std::wstring wstr=L"ПривЕт";

        transform(wstr.begin(), wstr.end(), wstr.begin(), towlower);

        std::wcout << wstr << std::endl;
}


/thread

Kroz ★★★★★
()
Ответ на: комментарий от Kroz

А включаешь — не работает

terminate called after throwing an instance of 'std::runtime_error'
  what():  locale::facet::_S_create_c_locale name not valid
P.S. ru_RU.UTF-8 прокатывает, но это только для отечественных машин.

quiet_readonly ★★★★
()
Последнее исправление: quiet_readonly (всего исправлений: 1)
Ответ на: комментарий от quiet_readonly

Значит нужно сгенерировать нужные локали (вероятно добить их в /etc/locale.gen и запустить locale-gen), либо брать имя локали из переменных окружения, например из LANG.

mashina ★★★★★
()
Ответ на: комментарий от mashina

Значит нужно сгенерировать нужные локали (вероятно добить их в /etc/locale.gen и запустить locale-gen), либо брать имя локали из переменных окружения, например из LANG.

Первый вариант оторван от реальности, генерировать что-то глобальное на компьютере пользователя не стоит. Второй неплох, но это только для Linux (ну может ещё под MacOS X).

quiet_readonly ★★★★
()
Ответ на: комментарий от quiet_readonly

У меня на локальной машине вот так заработало:

#include<iostream>
#include<iomanip> 
#include<string>
#include<algorithm> 

int main() {
   std::locale::global(std::locale(""));
   std::wcout.imbue(std::locale());
   auto& facet = std::use_facet<std::ctype<wchar_t>>(std::locale());
   std::wstring str = L"КУРВА, Я ПЕРДОЛЕ";
   std::wcout << str << std::endl;
   facet.tolower(&str[0], &str[0] + str.size());   
   std::wcout <<  str << std::endl;
}
$ g++ -std=c++11 pierdole.cpp 
$ ./a.out 
КУРВА, Я ПЕРДОЛЕ
курва, я пердоле
cherry-pick
()

А потом они говорят, что Qt — велосипед.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.