对utf-8字符串计算长度

对utf-8字符串计算长度

1.简介

在linux操作系统下,默认使用utf-8字符集,当程序中的在流中使用字符(ASCII)时用strlen()函数完全能够处理问题,但是在流中使用中文汉字时,strlen()就力不从心了。若更改字符集为GB2312,一个汉字等于两个字符,但是此更改不仅要修改文件保存的保存字符集,还要修改系统的字符集及终端的字符集。所以我通过对utf-8字符集的学习,自己编写了一个求utf-8字符编码的长度计算函数。


2.UTF-8 字符集编码格式

           编码                                                             长度(Byte)
      1               2               3            4        
0xxxxxxx                                                                        1

110xxxxx 10xxxxxx                                                       2

1110xxxx 10xxxxxx  10xxxxxx                                      3

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx                       4

从编码中第一列可看出:  1.最高位为0时,编码长度为1, 可存放一个ASCII字符。
                                           2.最高位为1,次高位为1,第6位为0时,编码长度为2。
                                           3.最高位为1,次高位为1,第6位为1,第5位为0时,编码长度为3,绝大多数汉字的utf-8编码的长度都为3。

                                           ....以此类推.....


3.函数原型
    void       GetUtf8Length (     char   const   *str ,             int     cnt[]       );
    返回值为空: 这里不去判断输入字符串指针是否安全,故无返回。(可以根据需求修改)
    char const *str: 输入字符串指针,并且告诉编译器,程序不能修改指针所指向地址里的值。
    int cnt[]: 这个数组用于存储各种长度字符的个数。
               cnt[0] 字符串中,各种长度字符的总和。
               cnt[1] 长度为1的字符总和, 也就是源字符串中ASCII字符的个数。
               cnt[2] 长度为2的字符总和。
               cnt[3] 长度为3的字符总和。
               cnt[4] 长度为4的字符总和。
               注: int cnt[5]; 这个声明需在调用GetUtf8Length函数的代码块作用域中定义。
                    数组初始化,全为0 如用: # include                         memset( cnt, 0, sizeof(int) * 5);


4.函数定义

void
GetUtf8Length( char const *str, int *cnt){

	while( *str != '\0' ){
		if( *str & 1<<7 ){/* 第8位(从右到左)为1*/
			if( *str & (1<<6) ){/*第7位为1*/
				if( *str & (1<<5) ){/*第6位为1*/
					if( *str & (1<<4)){/*第5位为1  11110xxx*/
						cnt[4]++,cnt[0]++,str += 4;/*4字节的字符总数加1,各种长度总数加1,指针向后移动4位*/
						continue;/*开始下次循环*/
					}

					cnt[3]++,cnt[0]++,str += 3;/* 1110xxxx*/
					continue;

				}

				cnt[2]++,cnt[0]++,str += 2;/*110xxxxx*/
				continue;

			}
		}

		cnt[1]++,cnt[0]++,str += 1;/*0xxxxxxx*/
		continue;

	}
}	
5.测试程序

/******************************************START******************************************************/
# include 
# include 
# include /*不用memset函数,可以不要*/

void GetUtf8Length( char const *str, int *cnt );

/******************************************MAIN******************************************************/
int
main( void ){

	char str[] = "这是一条UTF-8的文本,请数数aaaabbbbcccc*(是的.";
	int cnt[5];
	memset( cnt, 0, sizeof(int) * 4 );
	GetUtf8Length( str, cnt);
	printf( " 这条文本的字符共%d个 ; 其中汉字有%d个, 英文字符%d个\n", cnt[0], cnt[3], cnt[1] );

	return EXIT_SUCCESS;
}
/******************************************END*******************************************************/

/******************************************FUNC******************************************************/
void
GetUtf8Length( char const *str, int *cnt){

	while( *str != '\0' ){
		if( *str & 1<<7 ){
			if( *str & (1<<6) ){
				if( *str & (1<<5) ){
					if( *str & (1<<4)){
						cnt[4]++,cnt[0]++,str += 4;
						continue;
					}
					cnt[3]++,cnt[0]++,str += 3;
					continue;
				}
				cnt[2]++,cnt[0]++,str += 2;
				continue;
			}
		}
		cnt[1]++,cnt[0]++,str += 1;
		continue;
	}
}
/*********************************************END****************************************************/

6.运行图片

对utf-8字符串计算长度_第1张图片



                                                                          Writer:  Anden       Email:  [email protected]      Time:  2016.03.30

你可能感兴趣的:(C语言)