单字节字符与多字节字符的处理

 

我们还可以根据程序处理字符串时, 主要还是依赖标准库函数:c语言, glib, wchar

,相关概念

    可以在google上找一些编码发展历史与一些基本概念,: ucs-2, usc-4, utf8, utf16

    1.1 unicodeutf8

        Unicode只是一个符号集,它只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储。

        UNICODE 如何在网络上传输也是一个必须考虑的问题,于是面向传输的众多 UTFUCS Transfer Format)标准出现了,顾名思义,UTF8就是每次8个位传输数据,而UTF16就是每次16个位,只不过为了传输时的可靠性,从UNICODEUTF时并不是直接的对应,而是要过一些算法和规则来转换。UTF-8Unicode的实现方式之一。

 

    1.2 charsetencoding的区别?

        Charset/Encoding(字符集/编码)。Charset很容易和Encoding搞混,也是刚开始接触字符编码问题是最容易被晕掉的概念。字符集的概念,实际上,包含两个方面,一个,是字符的集合,即所谓的Charset,一个是编码方案,也就是所谓的Encoding。所谓字符的集合,意即一个字符集,定义了它所包含的所有符号,这实际上正是字符集名字的真正含义。也就是说,狭义上的字符集,并不包含编码方案,它仅仅是定义了哪些符号属于这个字符集。

   

    3.2看一个字符的unicodeutf8的工具   

    UltraEdit ->Edit->Hex Edit

 

    3.3 字符

    我们常说的字符是一个汉字是一个字符,一个ascii也是一个字符,所以一个字符可能对应多个字节.

 

, c语言的字符处理函数能来处理utf8编码的字符吗?

    2.1 字节与字符

    虽然c语言只提供单字节处理函数, glib提供的utf8处理的API,主要是对处理字符的,如果对于处理字节c的一些常用函数还是可以用的

    c的很字符串函数都是locale无关的,它们都是处理以'/0'为结尾的字节串,如:strcpy,strncpy,strcat,strncat,strcmp,strncmp,strdup,strchr,strtok

 

2.2 C函数strlen()总是返回字符串在内存中占据的字节数。

strlen()被用于该目的而被调用,不需要进行改动,但如果你要得到字符串的长度,你就能用宽字符处理函数g_utf8_strlen,

: char * a = “你我”   strlen(a) = 5; g_utf8_strlen(a,-1)=2  ;

 

2.3 Strncpy,strndup,strncmp..你必须搞清楚你处理的是字节还是字符,如果是字符哪就要用宽字符处理函数如: g_utf8_strncpy, g_utf8_strup, g_utf8_collate

:oma mms subject不能超过40ascii 字节,我们只能用strncpycut off而不能用g_utf8_strncpy

g_strncpy(tmpSubj, subjectP, MSG_SUBJECT_MAX_LENGTH);

 

2.4 单个字符的处理,所有涉及单个字符的处理都必要用宽字符处理函数:   

    : 取掉string中的空格

static void prv_strip_leading_blanks(const gchar **srcPP)

{

    gunichar c;

    const gchar *srcP = NULL;

    if (srcPP == NULL || *srcPP == NULL) return;

    srcP = *srcPP;

    c = g_utf8_get_char(srcP);   

    while (*srcP && g_unichar_isspace(c)) {

        srcP = g_utf8_next_char(srcP);

        c = g_utf8_get_char(srcP);

    }

    // chars need to be removed

    *srcPP = srcP;

}

2.5 g_strdup_printf(),g_strstrip ..utf8是安全的

2.6 g_strrevese是不安全的

 

   2.7 strcpy,既可以用于单字节字符集(ISO 8859-1),也可以用于多字节编码(UTF-8)的字符集,因为它们完成的任务无需了解一个字符究竟对应几个字节.

 

   2.8 strchr, 完成的任务则依赖于一个 字符编码成一个字节,因此对于UTF-8用处不大(如果在UTF-8字符串中寻找ASCII字符的话,strchr依然能正常工作)

   

,monolith的实际应用

    个人理解monolith中大部分都是utf8编码的,好像search库是utf16.localemgr中间件是专门处理locale相关的事务的,你可以取出系统中的字符集(charset)与编码方式(encoding)

    3.1 charsetencoding的使用

        : Email/Messaging send,我们要告诉postal当前系统的charsetencoding,这样接受者能准确的显示它们.

        /*! @brief Bodypart content type charset. */

#define ALP_POSTAL_PROPERTY_BODYPART_CONTENT_TYPE_CHARSET /

                ALP_POSTAL_PROPERTY(ALP_POSTAL_SERVICE_ID_COMMON, ALP_POSTAL_SERVICE_CLASS_ID_BODYPART, ALP_POSTAL_PROPERTY_TYPE_C_STRING, 15)

 

    /*! @brief Bodypart content location native charset encoding. */

#define ALP_POSTAL_PROPERTY_BODYPART_CONTENT_NATIVE_CHARSET /

                ALP_POSTAL_PROPERTY(ALP_POSTAL_SERVICE_ID_COMMON, ALP_POSTAL_SERVICE_CLASS_ID_BODYPART, ALP_POSTAL_PROPERTY_TYPE_C_STRING, 23)

   

/*! @brief Bodypart content transfer encoding. */

#define ALP_POSTAL_PROPERTY_BODYPART_CONTENT_TRANSFER_ENCODING /

                ALP_POSTAL_PROPERTY(ALP_POSTAL_SERVICE_ID_COMMON, ALP_POSTAL_SERVICE_CLASS_ID_BODYPART, ALP_POSTAL_PROPERTY_TYPE_C_STRING, 20)

 

3.2 当前monolith项目中处理多字节应用

    主要看你是处理字节还是处理字符?

    3.2.1涉及单个字符的处理的,要用宽字节处理函数,用指针取字符时要小心,如果是utf8的一定要用g_utf8_next_char,g_utf8_prev_char

1:设置字符串位置

        force_edit_set_cursor_position:

        /browser/src/alp_browser_page_callback.c:     force_edit_set_cursor_position(edit, g_utf8_strlen(in_initString, -1));

2:去掉字符串中的空格

        unified/msg_compose_contact_activity.c/ prv_strip_trailing_blanks

 

3.2.2明确要限制字符串个数的函数要用宽字节处理函数

        :contact vart的名子就是限制宽字符个数的

 

    其它用到utf8 处理函数的,用单字节处理也是一样用,都是处理/0结束的字符串.: g_utf8_collatestrcmp效果可能一样吧(个人理解)

 

3.5 strncpy与乱码的问题

    可能会出现乱码,因为utf8 是可变长编码,一个字符可能有三个字节组成,如果是数组定义的字节长度,哪么没办法,只能用strncpy

 

3.6 g_utf8_strncpy时一定要问问自己是不是在处理字符个数.

 

3.6 limited length是字节数还是字符数

    这要看具体的应用了要求了,限制字节个数比较明确,但要处理乱码问题;限制字符时字节个数就变的不定了,因为unf8是变长的编码方式.monolith中约%90都是限制字节个数.

    exchange关联的应用要一致,:contacts vcard名子是限制字符个数的.相应用这个名子也用一样.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值