Поиск независимого от платформы и сторонней библиотеки способа повторения строки UTF-8 или ее разделения на массив символов UTF-8.
Пожалуйста, опубликуйте фрагмент кода.
Решено: C++ повторяет или разбивает строку UTF-8 на массив символов?
Поиск независимого от платформы и сторонней библиотеки способа повторения строки UTF-8 или ее разделения на массив символов UTF-8.
Пожалуйста, опубликуйте фрагмент кода.
Решено: C++ повторяет или разбивает строку UTF-8 на массив символов?
Если я правильно понимаю, похоже, вы хотите найти начало каждого символа UTF-8. Если это так, то их было бы довольно просто разобрать (интерпретировать их — другое дело). Но определение того, сколько октетов задействовано, четко определено в RFC:
Char. number range | UTF-8 octet sequence
(hexadecimal) | (binary)
--------------------+---------------------------------------------
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Например, если lb
имеет первый октет символа UTF-8, я думаю, что следующее будет определять количество задействованных октетов.
unsigned char lb;
if (( lb & 0x80 ) == 0 ) // lead bit is zero, must be a single ascii
printf( "1 octet\n" );
else if (( lb & 0xE0 ) == 0xC0 ) // 110x xxxx
printf( "2 octets\n" );
else if (( lb & 0xF0 ) == 0xE0 ) // 1110 xxxx
printf( "3 octets\n" );
else if (( lb & 0xF8 ) == 0xF0 ) // 1111 0xxx
printf( "4 octets\n" );
else
printf( "Unrecognized lead byte (%02x)\n", lb );
В конечном счете, вам будет гораздо лучше использовать существующую библиотеку, как это было предложено в другом посте. Приведенный выше код может классифицировать символы в соответствии с октетами, но он не помогает «делать» что-либо с ними после завершения.
Решено с помощью крошечной независимой от платформы библиотеки UTF8 CPP:
char* str = (char*)text.c_str(); // utf-8 string
char* str_i = str; // string iterator
char* end = str+strlen(str)+1; // end iterator
do
{
uint32_t code = utf8::next(str_i, end); // get 32 bit code of a utf-8 symbol
if (code == 0)
continue;
unsigned char[5] symbol = {0};
utf8::append(code, symbol); // copy code to symbol
// ... do something with symbol
}
while ( str_i < end );
vector<uint32_t>
для сохранения слова? Если это так, то сравнение слов требует повторения вектора/массива и кажется довольно медленным...
- person stackunderflow; 18.05.2018
CPP UTF8 — это именно то, что вам нужно.
Попробуйте библиотеку ICU.
Без подготовки:
// Return length of s converted. On success return should equal s.length().
// On error return points to the character where decoding failed.
// Remember to check the success flag since decoding errors could occur at
// the end of the string
int convert(std::vector<int>& u, const std::string& s, bool& success) {
success = false;
int cp = 0;
int runlen = 0;
for (std::string::const_iterator it = s.begin(), end = s.end(); it != end; ++it) {
int ch = static_cast<unsigned char>(*it);
if (runlen > 0) {
if ((ch & 0xc0 != 0x80) || cp == 0) return it-s.begin();
cp = (cp << 6) + (ch & 0x3f);
if (--runlen == 0) {
u.push_back(cp);
cp = 0;
}
}
else if (cp == 0) {
if (ch < 0x80) { u.push_back(ch); }
else if (ch > 0xf8) return it-s.begin();
else if (ch > 0xf0) { cp = ch & 7; runlen = 3; }
else if (ch > 0xe0) { cp = ch & 0xf; runlen = 2; }
else if (ch > 0xc0) { cp = ch & 0x1f; runlen = 1; }
else return it-s.begin(); // stop on error
}
else return it-s.begin();
}
success = runlen == 0; // verify we are between codepoints
return s.length();
}
const char* const' to
char*'
- person topright gamedev; 18.05.2010