char16_t* next_c_u16(const char16_t* c) { if (IS_SURROGATE_PAIR(c[0], c[1]) == true) return (char16_t*)c + 2; return (char16_t*)c + 1; }
//utf16文字を一文字取り出す void ext_c_u16(char16_t* const dst, const char16_t* src,int* size) { int sz; if (IS_SURROGATE_PAIR(src[0], src[1]) == true) sz = 4; else sz = 2; memcpy(dst, src, sz); dst[sz/2] = char16_t(0); if(size) *size = sz; }
//utf16文字を比較する bool cmp_c_u16(const char16_t* c1, const char16_t* c2) { int K = bytes_c_u16(c1); int L = bytes_c_u16(c2); if (K != L) return false; bool issame = (memcmp(c1, c2, K) == 0); return issame; }
//文字のバイト数を取得 int bytes_c_u16(const char16_t* c) { if (IS_SURROGATE_PAIR(c[0], c[1]) == true) return 4; return 2; }
std::vector<std::u16string> split_u16(const char16_t* src, const char16_t* del) { char16_t tmp[10]; std::vector<std::u16string> result; std::u16string tmps; while (*src) { //デリミタを飛ばす const char16_t* p = src; while (cmp_c_u16(src, del) == true && *src != '\0') src = next_c_u16(src); //デリミタに遭遇するまで文字を追加し続ける while (cmp_c_u16(src, del) != true && *src != '\0') { ext_c_u16(tmp, src, nullptr);//一文字取り出す tmps += tmp; src = next_c_u16(src); } if (tmps.size()) { result.push_back(tmps); } tmps.clear(); } return result; }
int main() { setlocale(LC_ALL, ""); char16_t* u16 = (char16_t*)L"C:\\いろは\\山田\\abc\\"; std::ofstream f(L"c:\\test\\test.txt", std::ios::out | std::ios::binary); std::vector<std::u16string> ret = split_u16(u16, (char16_t*)L"\\"); for (size_t i = 0; i < ret.size(); i++) { wprintf(L"[%s]", (wchar_t*)ret[i].c_str()); } f.close(); return 0; }
[C:][いろは][山田][abc]
サロゲートペアの文字一覧はここから
WordPressで上記文字を入力したところなぜか記事の保存ができなかったので、実験2は画像にしている。