Требуется преобразовать строку с кириллицей типа std::u16string к нижнему регистру.
Что пробовал:
1) boost::algorithm::to_lower
2) std::use_facet<std::ctype<char16_t>>(std::locale("")).tolower(&test[0],&test[0] + test.size());
3) std::transform(test.begin(), test.end(), test.begin(), ::tolower);
Пробовал устанавливать перед этим локаль:
1) std::locale("");
2) std::locale("ru");
3) std::locale("RU");
4) std::locale("ru_RU"); - вызывается исключение
Во всех случаях результат преобразования строки u"Тест" равен: "5ab, а должен быть: тест
При этом текст на латинице преобразуется правильно. Строка с кириллицей типа std::wstring также преобразуется правильно.
Пример кода для воспроизведения:
std::locale("");
std::u16string test = u"Тест";
std::transform(test.begin(), test.end(), test.begin(), ::tolower);
Условия воспроизведения:
ОС: Windows 7 64Bit Eng
Компилятор: Visual Studio 2017 Community
Кодировка файла с исходником: UTF-8 с BOM
Поддержки Unicode в C++ нет(*), поэтому используйте сторонние средства. Одним из наиболее известных средств является ICU. Если собрать Boost с использованием ICU, то можно использовать Boost.Locale, которая может быть удобнее.
(*) Есть некоторые «ошмётки» Unicode в C++, но они не стоят внимания.
Преобразование строки в нижний регистр, а также "По поводу tolower и русских букв - опропобал на лине. Действительно, не работает. Чтобы нормально преобразовывать, нужно создать строку wchar_t и далее с нею работать функцией towlower из wchar.h" – skegg 1 дек '11 в 14:56
Пришел к такому рабочему решению:
#include <string>
#include <algorithm>
#include <cwctype>
int main()
{
setlocale(LC_ALL, "");
std::u16string test = u"Тест";
std::transform(test.begin(), test.end(), test.begin(), std::towlower);
return 0;
}
То есть использовать функцию towlower. Обязательно необходимо установить локаль. Проверял под Ubuntu 14 (32-64), Mac OS Sierra, Windows Server 2008. В целом нет уверенности что это правильный подход, ведь в описании сказано, что функция towlower предназначена для обработки символов типа wchar_t, а у меня тип char16_t и под Linux wchar_t имеет размер 4 байта. Так или иначе работает. Если есть более правильное решение прошу делиться в ответах.
Есть функция tolower, которая переводит символы в нижний регистр. Можно применить ее ко всем символам строки:
#include <algorithm>
#include <iostream>
#include <string>
#include <ctype.h>
int main() {
std::string s = "IaFFSjndsUFfE";
std::transform(s.begin(), s.end(), s.begin(), tolower);
std::cout << s << std::endl;
}
специально для минусаторов
#include <algorithm>
#include <iostream>
#include <string>
#include <ctype.h>
int main() {
std::string s ="тест";
std::transform(s.begin(), s.end(), s.begin(), tolower);
std::cout << s << std::endl;
}
рабочее решение
std::transform(test.begin(), test.end(), test.begin(), ::towlower);
Проверял под Ubuntu 14 (32-64), Mac OS Sierra, Windows Server 2008. Везде работает.
специально для минусаторов
#include <algorithm>
#include <iostream>
#include <string>
#include <ctype.h>
int main() {
std::string s = "БОЛЬШИЕ РУСКИЕ БУКВЫ";
std::transform(s.begin(), s.end(), s.begin(), ::towlower);
std::cout << s << std::endl;
}
Виртуальный выделенный сервер (VDS) становится отличным выбором
ListBig* self; выдаёт ошибку - error: 'ListBig' does not name a type ListBig* self;
Как легко удалить из строки начальные символы такие как пробел, табуляция или символ новой строки и тп
Если для Linux инструмент (или возможность в какой-либо ide) для просмотра оперативной памяти процесса, наподобие инструмента просмотра памяти...
Эта код добавляет удаляет обновляет данные из БД все прекрасно работает но при нажатии на кнопки READ она все выводит в консоль, да так и продуманно...