Как мне индексировать (не все ascii) строку utf8 в C? - PullRequest
0 голосов
/ 25 января 2019

Я хочу проиндексировать символы в строке utf8, которая не обязательно содержит только символы ascii. Я хочу такое же поведение, как в javascript:

> str = "lλך" // i.e. Latin ell, Greek lambda, Hebrew lamedh
'lλך'
> str[0]
'l'
> str[1]
'λ'
> str[2]
'ך'

Следуя совету UTF-8 Everywhere , я представляю свою строку со смешанной длиной символов так же, как и любое другое строковое значение в c, и не использую wchars.

Проблема в том, что в C невозможно получить доступ к 16-му символу строки: только 16-й байт . Поскольку λ кодируется двумя байтами в utf-8, я должен получить доступ к 16-му и 17-му байтам строки, чтобы распечатать один λ.

Для справки, вывод:

#include <stdio.h>                                                                                                    

int main () {                                                                                                         
  char word_with_greek[] = "this is lambda:_λ";                                                                       
  printf("%s\n",word_with_greek);                                                                                     
  printf("The 0th character is: %c\n", word_with_greek[0]);                                                           
  printf("The 15th character is: %c\n",word_with_greek[15]);                                                          
  printf("The 16th character is: %c%c\n",word_with_greek[16],word_with_greek[17]);                                    
  return 0;                                                                                                           
}   

есть:

this is lambda:_λ
The 0th character is: t
The 15th character is: _
The 16th character is: λ

Есть ли простой способ разбить строку на символов ? Не кажется слишком сложным написать функцию, которая разбивает строку на wchars, но я думаю, что кто-то уже написал это, но я не могу ее найти.

Ответы [ 2 ]

0 голосов
/ 25 января 2019

Вам следует обратиться к коду, лежащему в основе emacs, потому что emacs не только реализовал все возможные функции преобразования, но и реализовал их хорошо, лучше, чем почти все другие редакторы.

Начните чтение с API относительно многобайтовых символов и посмотрите, как они реализованы.

0 голосов
/ 25 января 2019

Это зависит от того, какими могут быть ваши юникод-символы. Большинство строк ограничены Basic Multilanguage Plane . Если ваш (не случайно по самой своей природе: по крайней мере, нет риска для эмодзи ...), вы можете использовать char16_t для обозначения любого персонажа. КСТАТИ wchar_t по крайней мере так же велико, как char16_t, поэтому в этом случае можно безопасно использовать.

Если ваш сценарий может содержать символ эмодзи или другие символы, отсутствующие в BMP, или просто если вы не уверены, единственный надежный способ - преобразовать все в char32_t, потому что любой символ Юникода (по крайней мере, в 2019 году ...) в качестве кода, использующего менее 32 бит.

Преобразование для UTF8 в 32 (или 16) бит Unicode не так сложно, и может быть закодировано вручную, Википедия содержит достаточно информации для этого. Но вы найдете тонны библиотек, в которых это уже написано и протестировано, в основном это отличный libiconv, но версия стандартной библиотеки C для C содержит функции для преобразований UTF8. Не так хорошо, но полезно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...