如何在C中索引一个(并非全部ascii)utf8字符串?

时间:2019-01-25 07:00:13

标签: c unicode utf-8

我想索引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个 byte 。因为λ在utf-8中使用两个 bytes 进行编码,所以我必须访问字符串的第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 :(得分:0)

这取决于您的Unicode字符可以是什么。大多数字符串仅限于Basic Multilanguage Plane。如果您的字符是字符(不是偶然的,因为它们的性质:至少没有表情符号的风险...),则可以使用char16_t来表示任何字符。 BTW wchar_t至少与char16_t一样大,因此在这种情况下可以安全地使用它。

如果脚本中可以包含表情符号字符或BMP中没有的其他字符,或者只是不确定,则唯一安全的方法是将所有内容都转换为char32_t,因为任何Unicode字符(至少在2019年都可以。) )作为少于32位的代码。

将UTF8转换为32(或16)位unicode并不难,可以手工编码,Wikipedia包含足够的信息。但是您会发现很多已经过编码和测试的库,主要是出色的libiconv,但是C标准库的C11版本包含用于UTF8转换的函数。不太好但是有用。

答案 1 :(得分:0)

您应该查阅emacs背后的代码,因为emacs不仅实现了所有可能的转换功能,而且还实现得很好,比几乎所有其他编辑器都要好。

api concerning the multibyte chars ans开始阅读,了解它们是如何实现的。