キャラクターを大文字にするのは複雑な仕事であることがわかりました。基本的なASCII文字セットから抜け出す場合、文字の大文字と小文字の規則は、実際にはアプリケーションが実行されているロケールに依存します。
デモアプリケーションとして、文字「i」(ドット付き)と文字「i」(ドットなし)を大文字にしようとしています。現在、en_USでは、「i」(ドット付き)は「I」に大文字で、「i」(ドットなし)は存在しません(ただし、「I」は大文字のままです)。
ただし、トルコ語(tr_TR.UTF-8)に切り替える場合、「i」(ドット付き)は「İ」(ドット付き)に大文字にする必要があり、「ı」(ドットなし)は「I」に大文字にする必要があります(これもドットなし)。小文字はこれらの操作を逆にする必要があります。
iİıI --> İİII (tr_TR.UTF-8)
iİıI --> IİII (en_US.UTF-8)
今、私はこれをCで完璧に行うことができます。Haskellでこれを行うにはどうすればよいですか?私が行うすべての検索は、ロケールを認識しないData.Char.toUpperを直接指し示します。ロケールを認識する関数は見つかりませんでした。
これがCのコードサンプルです。Linuxマシンで実行しています。
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <wctype.h>
#include <string.h>
#include <errno.h>
wchar_t latin_small_sharp_s[5] = {0x00df, 0x00df, 0x0053, 0x0053, 0};
wchar_t turkish_is[5] = {0x0069, 0x0130, 0x0131, 0x0049, 0};
char multibyte_turkish_is[7] = {0x69, 0x01, 0x30, 0x01, 0x31, 0x49, 0};
void print_in_locale (const char *locale, const wchar_t *str, const size_t len) {
wchar_t *dest = calloc(len * 2, sizeof(wchar_t));
int i;
if (!setlocale(LC_CTYPE, locale)) {
fprintf(stderr, "Locale %s failed with error: %s", locale, strerror(errno));
exit(1);
}
for (i = 0; i < len; i++) {
dest[i] = towupper(str[i]);
}
printf("%ls, %ls\n", str, dest);
free(dest);
}
int main () {
print_in_locale("de_DE.utf8", latin_small_sharp_s, 5);
print_in_locale("tr_TR.utf8", turkish_is, 5);
print_in_locale("de_DE.utf8", turkish_is, 5);
}
「locale_test.c」に保存した場合は、コマンドラインで次のコマンドを使用して実行できます...
gcc -o locale_test locale_test.c && ./locale_test