Продвинуть UTF-8 персонажа к следующему - PullRequest
3 голосов
/ 05 февраля 2011

Я хочу изменить символ UTF-8 (который находится в массиве gchar), чтобы он получал значение следующего символа в соответствии со стандартом.Я использую glib и не вижу такой функции.Я думаю о возможном решении, но это потребует, возможно, больше усилий, и, конечно, оно не будет самым эффективным, так как я не знаю слишком много о кодировках.Есть ли библиотека, которая может это сделать?Гугл не помог.

Ответы [ 2 ]

6 голосов
/ 05 февраля 2011

По сути, это просто добавление и перенос по модулю 64. Рассматривайте байты символа как «цифры». Вы увеличиваете последний байт и, если он переполняется, сбрасываете его до наименьшего возможного значения и увеличиваете второй до последнего байта.

Например, простое приращение:

e0 b0 be -> e0 b0 bf

Приращение с одним переносом:

e0 b0 bf -> e0 b1 80

И приращение с двойным переносом:

e0 bf bf -> e1 80 80

Когда вы увеличиваете число за последним символом заданного размера, вам нужно перейти к первому символу следующего размера, что, конечно, нельзя сделать на месте в середине строки. *

2 голосов
/ 05 февраля 2011

Если вы хотите избежать прямого взлома байтов, вы можете сделать что-то вроде этого (не проверено):

gunichar c;
int len, old_len;
char buf[6];

c = g_utf8_get_char(s);
old_len = g_unichar_to_utf8(c, NULL);
c += 1;
len = g_unichar_to_utf8(c, buf);
if (len == old_len) {
  memcpy(s, buf, len);
} else {
  /* something more complex adjusting s length */
}

Конечно, написание этого вручную даст вам более оптимизированный код. Незначительная оптимизация, описанная выше, может использовать g_utf8_next_char (), чтобы получить следующую строковую позицию и вычислить old_len из нее, вместо того, чтобы независимо вычислять old_len.

...