linux c语言 utf8读写,关于在C程序中处理UTF-8文本的方法详解

本文详细介绍了如何在C语言中处理UTF-8编码的文本,特别是使用GLib库来操作UTF-8字符串。通过示例展示了如何计算UTF-8字符串长度、定位字符、遍历和比较UTF-8字符,以及判断空白字符和换行符,最终解决特定问题。
摘要由CSDN通过智能技术生成

UTF-8

互联网的普及, 强烈要求出现一种统一的编码方式. UTF-8就是在互联网上使用最广的一种unicode的实现方式. 其他实现方式还包括UTF-16和UTF-32, 不过在互联网上基本不用.

重复一遍, 这里的关系是, UTF-8是Unicode的实现方式之一.

UTF-8最大的一个特点, 就是它是一种变长的编码方式. 它可以使用1~6个字节表示一个符号, 根据不同的符号而变化字节长度.

UTF-8的编码规则

UTF-8的编码规则很简单, 只有两条:

1) 对于单字节的符号, 字节的第一位设为0, 后面7位为这个符号的unicode码. 因此对于英语字母, UTF-8编码和ASCII码是相同的.

2) 对于n字节的符号(n>1), 第一个字节的前n位都设为1, 第n+1位设为0, 后面字节的前两位一律设为10. 剩下的没有提及的二进制位, 全部为这个符号的unicode码.

如果你对 UTF-8 编码不是非常了解,就不要试图在 C 程序中徒手处理 UTF-8 文本。如果你对 UTF-8 非常了解,就更没必要这样做。找一个提供了 UTF-8 文本处理功能并且可以跨平台运行的 C 库来做这件事吧!

GLib 就是这样的库。

从问题出发

下面的这段文本是 UTF-8 编码的(我之所以如此确定,是因为我用的是 Linux 系统,系统默认的文本编码是 UTF-8):

我的 C81 每天都在口袋里

@

我需要在 C 程序中读入这些文本。在读到 '@' 字符时,我需要判定 '@' 左侧与之处于同一行的文本是否都是空白字符。

简单起见,我忽略了文件读取的过程,将上述文本表示为 C 字符串:

gchar *demo_text =

"我的 C81 每天都在口袋里\n"

" @";

注:在 GLib 中,gchar 就是 char,即 typedef char gchar;

下文,当我说『demo_text 字符串』时,指的是以 demo_text 指针的值为基地址的 strlen(demo_text) + 1 个字节的内存空间,这是 C 语言字符串的基本常识。

UTF-8 文本长度与字符定位

为了模拟程序读到 '@' 字符这一时刻,我需要用一个 char * 类型的指针对 demo_text 字符串中的 '@' 字符进行定位。

'@' 字符在 demo_text 的末尾。我需要一个偏移距离,而这个偏移距离就是 demo_text 字串在 UTF-8 编码层次上的长度,通过这个偏移距离,我可以从 demo_text 字符串的基地址跳到 '@' 字符的基地址。

GLib 提供了 g_utf8_strlen 函数计算 UTF-8 字符串长度,因此我可以得到从 demo_text 字串的基地址到 '@' 字符基地址的偏移距离:

glong offset = g_utf8_strlen(demo_text, -1);

结果是 38,恰好是 demo_text 字符串在 UTF-8 编码层次上的长度(不含字串结尾的 null 字符,亦即 '\0' 字符)。

g_utf8_strlen 的原型如下:

glong g_utf8_strlen(const gchar *p, gssize max);

注:glong 即 long,而 gssize 即 signed long。

g_utf8_strlen 第二个参数 max 的设定规则如下:

如果它是负数,那么就假定字符串是以 null 结尾的(这是 C 字符串常识),然后统计 UTF-8 字符的个数。

如果它为 0,就是不检测字符串长度……这个值纯粹是出来打酱油的。

如果它为正数,表示的是字节数。g_utf8_strlen 会按照字节数从字符串中截取字节,然后再统计所截取的字节对应的 UTF-8 字符的个数。

有了偏移距离,就可以在 demo_text 中定位 '@' 字符了,即:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值