C语言,关于UTF8的编码问题

时间:2023-01-05 09:33:38
char ps[]="字符串编码";//VC 
char *pst=ANSIToUTF8(ps);//ANSIToUTF8就会把ps数组中的内容从ASCII编码编程UTF8
printf("%d",strLengthUTF8(pst));//将会显示长度是5
printf("%d",strSizeUTF8(pst));//将会显示大小是10

问题一是,如何获取UTF8编码的一个单位,比如:“字”,“符”,“串”等,即如:strcharUTF8(pst,"串");
问题二是,如果获取了比如pz=“字”的指针,如何输出它,printf("%c",pz)肯定不行,printf("%s",pz)会输出字符串编码也不行,



5 个解决方案

#1


答问题一:获取UTF8编码的一个单位必须按照UTF8的编码规范来做,编码规范自己去找,因为远远不止10000个字节,这里贴不下。其实它的中心思想很简单,就是由一个字节的最高几位(根据情况不同位数不定)来判别下一个字节是否属于同一个字。

答问题二:如果系统支持(例如在Linux下,环境变量指示采用UTF8编码)直接用 printf("%s",pst) 就可以。如果系统不支持(例如在windows下),你必须把UTF8转换成系统缺省的ANSI编码来输出,或者转换成Unicode 用unicode版的 wprintf(L"%s", pst) 来输出。

#2


1.首先不管什么编码的汉字,都是二进制编码。在C语言里面,都是字符数组。所说的一个单位,只是为了知道这个utf8字是几字节的。下面的函数是sphinx的解码函数,把一个p指向的utf8字符串解出第一个2字节的ucs-2字符,并返回该字符的utf8所占的长度,即你说的一个单位。另外,中文所在范围的utf8编码都是3字节的。
2.说了是字符串,当然是printf %s,只要你的终端输出的编码设置是utf8,终端就能显示正确的汉字字符。
int utf8decode(const char *p, unsigned short *codep)
{
    if(p == NULL || binit == 0){
        return -1;
    }

    unsigned char c = *p;
    if ( c == 0 ){
        *codep = 0;
        return 0;
    }
    p++;

    // check for 7-bit case
    if ( c<128 ){
        *codep = c;
        return 1;
    }

    // get number of bytes
    int len = 0;
    while ( c & 0x80 ){
        len++;
        c <<= 1;
    }

    // check for valid number of bytes
    if ( len<2 || len>4 ){
        return -2;
    }
    int i = len - 1;
    *codep = ( c>>len );
    do{
        if ( !(*p) )
            return 0; // unexpected eof

        if ( ((*p) & 0xC0)!=0x80 ) //10xxxxxx
            return -3; // invalid code

        *codep = ( (*codep) << 6 ) + ( (*p) & 0x3F ); //( code<<6 ) + ( 10xxxxxx & 111111 )
        i--;
        p++;
    } while ( i );

    return len;
}

#3


你得先弄清楚UCS,Unicode,UTF-8的关系。网上这方面的文章相当多,google一下吧。

C/C++里的宽字符是UCS2编码,也就是ISO 100646,是一个字符集,UTF-8是它的一种存储格式。
这中间存在一个转换过程,规则如下。
U-00000000 - U-0000007F:  0xxxxxxx
U-00000080 - U-000007FF:  110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF:  1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF:  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF:  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF:  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
左边的是UCS2编码,右边是UTF8编码。
例如“汉”字的Unicode编码是6C49,这是C语言能看懂的编码。6C49在0800-FFFF之间,对应着“U-00000800 - U-0000FFFF:  1110xxxx 10xxxxxx 10xxxxxx”。
将6C49写成二进制是:01101100 01001001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89,这才是存放在UTF8文件里的编码。

所以标准C是不能直接处理UTF8的文件的,需要先将UTF8转成UCS。网上有很多类似的算法,自己其实也可以写一个。

#4


学习了。。。

#5


看看下面这个帖子吧,绝对可以找到你的答案!!

Unicode: What You Can Do About It Today

http://www.cprogramming.com/tutorial/unicode.html

#1


答问题一:获取UTF8编码的一个单位必须按照UTF8的编码规范来做,编码规范自己去找,因为远远不止10000个字节,这里贴不下。其实它的中心思想很简单,就是由一个字节的最高几位(根据情况不同位数不定)来判别下一个字节是否属于同一个字。

答问题二:如果系统支持(例如在Linux下,环境变量指示采用UTF8编码)直接用 printf("%s",pst) 就可以。如果系统不支持(例如在windows下),你必须把UTF8转换成系统缺省的ANSI编码来输出,或者转换成Unicode 用unicode版的 wprintf(L"%s", pst) 来输出。

#2


1.首先不管什么编码的汉字,都是二进制编码。在C语言里面,都是字符数组。所说的一个单位,只是为了知道这个utf8字是几字节的。下面的函数是sphinx的解码函数,把一个p指向的utf8字符串解出第一个2字节的ucs-2字符,并返回该字符的utf8所占的长度,即你说的一个单位。另外,中文所在范围的utf8编码都是3字节的。
2.说了是字符串,当然是printf %s,只要你的终端输出的编码设置是utf8,终端就能显示正确的汉字字符。
int utf8decode(const char *p, unsigned short *codep)
{
    if(p == NULL || binit == 0){
        return -1;
    }

    unsigned char c = *p;
    if ( c == 0 ){
        *codep = 0;
        return 0;
    }
    p++;

    // check for 7-bit case
    if ( c<128 ){
        *codep = c;
        return 1;
    }

    // get number of bytes
    int len = 0;
    while ( c & 0x80 ){
        len++;
        c <<= 1;
    }

    // check for valid number of bytes
    if ( len<2 || len>4 ){
        return -2;
    }
    int i = len - 1;
    *codep = ( c>>len );
    do{
        if ( !(*p) )
            return 0; // unexpected eof

        if ( ((*p) & 0xC0)!=0x80 ) //10xxxxxx
            return -3; // invalid code

        *codep = ( (*codep) << 6 ) + ( (*p) & 0x3F ); //( code<<6 ) + ( 10xxxxxx & 111111 )
        i--;
        p++;
    } while ( i );

    return len;
}

#3


你得先弄清楚UCS,Unicode,UTF-8的关系。网上这方面的文章相当多,google一下吧。

C/C++里的宽字符是UCS2编码,也就是ISO 100646,是一个字符集,UTF-8是它的一种存储格式。
这中间存在一个转换过程,规则如下。
U-00000000 - U-0000007F:  0xxxxxxx
U-00000080 - U-000007FF:  110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF:  1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF:  11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF:  111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF:  1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
左边的是UCS2编码,右边是UTF8编码。
例如“汉”字的Unicode编码是6C49,这是C语言能看懂的编码。6C49在0800-FFFF之间,对应着“U-00000800 - U-0000FFFF:  1110xxxx 10xxxxxx 10xxxxxx”。
将6C49写成二进制是:01101100 01001001, 用这个比特流依次代替模板中的x,得到:11100110 10110001 10001001,即E6 B1 89,这才是存放在UTF8文件里的编码。

所以标准C是不能直接处理UTF8的文件的,需要先将UTF8转成UCS。网上有很多类似的算法,自己其实也可以写一个。

#4


学习了。。。

#5


看看下面这个帖子吧,绝对可以找到你的答案!!

Unicode: What You Can Do About It Today

http://www.cprogramming.com/tutorial/unicode.html