C++ で英語以外の文字を使用して tolower() を実行しようとすると、正常に動作しません。その問題を検索したところ、ロケールに関する何かに出くわしましたが、その最善の解決策についてはわかりません。
私のサンプルコードは以下の通りです:
printf("%c ",tolower('Ü'));
残念ながら、標準の C++ ライブラリには、英語以外のすべての可能な文字の大文字と小文字を変更するための十分なサポートがありません (大文字と小文字の違いがある文字に関しては)。この制限は、C++ 標準が、1 つの文字とその大文字と小文字のバリエーションが 1 つのchar
オブジェクト (またはwchar_t
ワイド文字のオブジェクト) を占有すると仮定し、英語以外の文字が true であることが保証されていないことによって発生します (また、文字はコード化されています)。
お使いの環境で関連する文字にシングルバイト エンコーディングが使用されている場合は、次のようにして必要な結果が得られる可能性があります。
std::cout << std::tolower('Ü', locale());
ワイド文字を使用すると、おそらくより多くの運が得られます。
std::wcout << std::tolower(L'Ü', locale());
しかし、それでも正しい結果は得られませんtoupper(L'ß')
。これは 2 文字のシーケンスになりますL"SS"
)。
すべての文字のサポートが必要な場合は、ICU ライブラリ、特にケース マッピングに関する部分を参照してください。
Bart が示したように、C++ は単にマルチバイト エンコーディングを好みません。幸いなことに、Boost.Local を使用すると、あまり手間をかけずにこれを解決できます。簡単な例を次に示します。
#include <iostream>
#include <locale>
#include <boost/locale.hpp>
int main() {
boost::locale::generator gen;
std::locale loc = gen("en_US.UTF-8");
std::string line;
while (std::getline(std::cin, line))
std::cout << boost::locale::to_lower(line, loc) << '\n';
}
コンパイルするには、Boost.Locale ライブラリにリンクする必要があります。
g++ -lboost_locale lower.cpp -o lower
そして、それを実行すると、次のようになります。
$ ./main <<< 'ICH HÄTTE GERNE EINEN SÜßEN HASEN'
ich hätte gerne einen süßen hasen