Получить "char" многобайтового символа в linux / mac - PullRequest
0 голосов
/ 28 декабря 2018

У меня есть и std :: string с символами utf-8 (некоторые латинские, некоторые нелатинские) в linux и mac.

Как мы знаем, размер символа utf-8 не фиксирован, а некоторыеиз символов не просто 1 байт (как обычные латинские символы).

Вопрос в том, как мне получить символ со смещением i ?

Имеет смысл использовать тип данных int32 для хранения символа, но как мне получить этот символ?

Например:

std::string str = read_utf8_text();
int c_can_be_more_than_one_byte = str[i]; // <-- obviously this code is wrong

Важно отметить, что I не знать размер символа в смещении i .

1 Ответ

0 голосов
/ 28 декабря 2018

Это очень просто.

Во-первых, вы должны понять, что вы не можете вычислить позицию без итерации строки (это очевидно для символов переменной длины)

Во-вторых, вам нужно помнить, чтов utf-8 символы могут составлять 1-4 байта, и в случае, если они занимают более одного байта, все завершающие байты имеют 10 значащих битов.Итак, вы просто считаете байты, игнорируя их, если (byte_val & 0xC0) == 0x80.

К сожалению, сейчас в моем распоряжении нет компилятора, поэтому, пожалуйста, будьте любезны с возможными ошибками в коде:

int desired_index = 19;
int index = 0;
char* p = my_str.c_str(); 
while ( *p && index < desired_index ){
  if ( (*p & 0xC0) != 0x80 ) // if it is first byte of next character
    index++;
  p++;
}

// now p points to trailing (2-4) bytes of previous character, skip them
while ( (*p & 0xC0) == 0x80 )
  p++;

if ( *p ){
  // here p points to your desired char
} else {
  // we reached EOL while searching
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...