C++でunicodeについて学んでいますが、正しく動作させるには苦労しています。私は個々の文字をuint64_tとして扱おうとします。私が必要とするのは、文字を印刷するだけであれば機能しますが、問題は大文字に変換する必要があることです。大文字を配列に格納し、小文字の場合と同じインデックスを使用するだけですが、より洗練されたソリューションを探しています。私はこれと似たようなものを見つけましたquestion答えのほとんどはワイド文字を使っていますが、これは私が使うことのできないものです。ここに私がしようとしたものである:C++でunicode文字を大文字に変換する方法
#include <iostream>
#include <locale>
#include <string>
#include <cstdint>
#include <algorithm>
// hacky solution to store a multibyte character in a uint64_t
#define E(c) ((((uint64_t) 0 | (uint32_t) c[0]) << 32) | (uint32_t) c[1])
typedef std::string::value_type char_t;
char_t upcase(char_t ch) {
return std::use_facet<std::ctype<char_t>>(std::locale()).toupper(ch);
}
std::string toupper(const std::string &src) {
std::string result;
std::transform(src.begin(), src.end(), std::back_inserter(result), upcase);
return result;
}
const uint64_t VOWS_EXTRA[]
{
E("å") , E("ä"), E("ö"), E("ij"), E("ø"), E("æ")
};
int main(void) {
char name[5];
std::locale::global(std::locale("sv_SE.UTF8"));
name[0] = (VOWS_EXTRA[3] >> 32) & ~((uint32_t)0);
name[1] = VOWS_EXTRA[3] & ~((uint32_t)0);
name[2] = '\0';
std::cout << toupper(name) << std::endl;
}
私は、これは文字IJ
をプリントアウトすることを期待しかし、それは始まり(ij
)にあったように、現実には、同じ文字を出力します。
(EDIT:OK、私は、標準C++ hereでのUnicodeのサポートについての詳細を読んで、私の最善の策は、このタスクのためにICUやBoost.localeのようなものを使用することであるように思えC++、本質的に扱います。 std :: stringをバイナリデータのBLOBとして扱うので、Unicode文字を大文字にするのは簡単ではないようです。uint64_tを使った私のハックな解決法は、C++標準ライブラリICUを使用して上記の動作を達成する方法の例に感謝します)
Unicodeが固定幅エンコーディングであるとふりをしないでください。 –
@NicolBolas申し訳ありませんが、私はunicodeでとても慣れていません。普通の文字列を使用しようとしましたが、1文字で作業することができませんでした。 – Linus
非常に特殊なコンパイラを使用しない限り、 'std :: locale :: global(std :: locale(" sv_SE.UTF8 "))'はWindowsと互換性がありません。 MicrosoftのランタイムはUTF-8ロケールをサポートしていません。 'setlocale'のドキュメントを参照してください。 –