Pull to refresh

Comments 17

Это не C++, а Win32 API. А что ты в Линуксе будешь делать?!

ICU есть под Linux. Я именно под ним первый раз и встретился с этой библиотекой. Раньше при попытке собрать что-то старое с ней часто были проблемы, во всяком случае у меня.
https://github.com/unicode-org/icu/releases/tag/release-75-1

Вторую часть абзаца я пропустил. Но тогда всю статью можно было ограничить только этой фразой:

Если вы работаете с библиотекой International Components for Unicode (ICU), то можете использовать u_strToUpper и u_strToLower.

И даже так: «Обязательно используйте u_strToUpper и u_strToLower из библиотеки ICU!»

Так Реймонд и дает рекомендацию: используйте ICU.

Я бы дал более широкую рекомендацию: не используйте строки (и функции над ними) из стандартной библиотеки C++. Они просто плохи во всех отношениях.

Максимум, на что они сгодятся - это отладочное логирование и использованием только ASCII символов. Во всех остальных случаях лучше искать библиотечные вариант (e.g. ICU/Qt)

Я думаю, любая либа на С++, умеющая в строки, так или иначе является обёрткой над ICU. Оно и неудивительно, в ICU есть буквально всё, что нужно.

Во-первых, std::tolower — это неадресуемая функция.

Что-то странное. На cppreference ни слова про это нет. Там сказано, что нельзя ее исползовать напрямую, потому что ей надо, чтобы параметр был unsigned char, а в контейнерах или int или char.

Наверное, потому что взять адрес от нее не тривиальная задача
https://coliru.stacked-crooked.com/view?id=300e31f9697b1fbc

#include <cctype>
#include <clocale>
#include <iostream>
#include <cxxabi.h>

 
int main()
{
    auto names = {
        typeid((int (*)(int))&std::tolower).name(),
		typeid(&std::tolower<char>).name(),
		typeid(&std::tolower<int>).name(),
		typeid(&std::tolower<wchar_t>).name(),
		typeid(&std::tolower<char32_t>).name(),
		typeid(&std::tolower<char8_t >).name(),
		typeid(&std::tolower<double>).name()
	};
	for(const auto&name:names) {
		int status;
		std::cout << name << " = " << abi::__cxa_demangle(name, NULL, NULL, &status) << '\n';
	}
}
PFiiE = int (*)(int)
PFccRKSt6localeE = char (*)(char, std::locale const&)
PFiiRKSt6localeE = int (*)(int, std::locale const&)
PFwwRKSt6localeE = wchar_t (*)(wchar_t, std::locale const&)
PFDiDiRKSt6localeE = char32_t (*)(char32_t, std::locale const&)
PFDuDuRKSt6localeE = char8_t (*)(char8_t, std::locale const&)
PFddRKSt6localeE = double (*)(double, std::locale const&)


Наверное, потому что взять адрес от нее не тривиальная задача

Но ведь ваш пример демонстрирует обратное!

Правильно использовать C++ `template< class CharT > CharT tolower( CharT ch, const locale& loc )`, а не C.

И она вам сможет два символа в один сконвертировать? Или один в два? И с utf-8 умеет работать?

Хорошо на C#, написал "Hello, World!".ToLower(), и всё

В случае с char - char ToLower('А')

В C#, к примеру, "fl".ToUpper() не работает корректно, если предварительно нормализацию не сделать. Со сложными символами не всё так просто.

Но даже так, как будто бы это легче чем то, что мы видим в C++

Ну да ладно, C# для этого и бьл создан

Sign up to leave a comment.

Articles