UTF-8编码数据在命令行终端编织成表格并输出

UTF-8编码数据在命令行终端编织成表格并输出


1.简介       
         我最近在Fadore23操作系统上学习C语言,发现在学习数据结构与算法这方面知识的时候,数据域中常常都只有一个简单类型数据或者是一个字符串,这样纯学算法而不去考虑数据结构,学到最后觉得很空,因为算法的本质是去操作数据。后来突发奇想,想去实现一个类似于mysql一样的数据库,当然实现这样一个数据库对现阶段的我肯定是个遥远梦想,但是为了梦想总是得迈出步伐,而我的第一步就是对单表进行增、删、改、查。
           众所周知,database都是有命令行终端进行操作的(sqlserver除外),那么数据以表格的形式在终端打印就成了我的第一个问题,为了后面的学习,我必须解决这个问题,通过了两天的努力,就有了今天的这篇博文,或许下面的代码效率低,也或许我的设计结构就不对,但是这是我的第一版,实现了自己的需求,后面我有了新的想法,我会不断的完善,或者重写。若您对我的代码有什么好的建议或者意见,请Email联系我。( Email: andensemail@163.com  ) 对于您的关注我深表感激。

先上两张图看看^_^~







2.最需要解决的问题

   Linux系统常用的是UTF-8编码,一个UTF-8的汉字在内存占用三个字节,而在终端打印时,它只占用二个字符的位置,那么表格的格式(各字段对齐)成了主要问题。


3.数据结构介绍
               typedef      struct         table {  
                           char *line;//字符串指针
                           struct table *pNext;//后续节点指针
                }      TABLE,    *PTABLE;

          将需要写在表格一行中的数据有规则的组合成一个字符串,放在动态内存中。然后创建一个TABLE节点Tnode,让Tnode.line指向字符串的首地址,而一张表格是由多行字符串组成的,那就用一个以TABLE 为节点的链表表示。 Tnode.pNext指向下一个行字符串。当需要将表格打印在终端时,只要遍历打印这个链表就行。



4.接口函数介绍(   我就写了三个  )
  
     a. 打开一张表格
             PTABLE OpenTable(  char   symble1,   char  symble2, char  *tableName, char   *tableTail, char   **data    );

                           char symble1: 这个符号用于画表格的外边框
                           char symble2: 这个符号用于画表格内行的分格,而列我用的是空白分格
                           char *tableName: 表格的名字
                           char *tableTail: 表格的尾行,用于写一些统计数据,本程序只实现了统计数据的个数,后面有需求时我再完善,统计数据用一个 ‘$’号,写在文本中。
                           chr  **data: 这个就是要插入表格的数据,是一个字符串数组,长度任意,但最后一个字符指针指向  NULL
                            return :          PTABLE数据类型的,是一个TABLE的指针。
                                
             使用:   PTABLE     pHead    =      NULL;//定义一个表的头指针                                           
                            *data[10] = {
                                          "学号 姓名 性别 年龄 年级 班级 语文成绩 数学成绩 英语成绩 总成绩",
                                          "2008 王小晨 男 10 4 丙 95.5 100 98.5 294",
                                          "2009 张胜 男 10 4 丙 94.5 99 97.5 291",
                                          "2010 刘倩 女 10 4 丙 90.5 100 95.5 286",
                                          "2011 Mary 女 10 4 甲 99.5 100 95.5 295",
                                           NULL
                             };// 每个字段间可用 空格,逗号,问号,感叹号格开。
                            pHead    =      OpenTable(      '*'   ,    '-'     ,      "成绩表"    ,     "共计 $ 人"     ,      data       );//本函数的调用


    b.在命令行终端打印表格
            void     PrintTable(     PTABLE pHead     );

                           PTABLE    pHead:     是表指针,表格链表中每个节点都必须是  TABLE    类型的。
                           return          void          此函数返回值为空,我们用的主要是这个函数的副作用遍历调用C语言的   I  / O   库函数,在命令行终端打印。
           使用:PrintTable(   pHead    );

    c. 关闭一张表格
          void      CloseTable( PTABLE pHead );

                            PTABLE    pHead: 是表指针,表格链表中每个节点都必须是  TABLE    类型的。
                            return          void     此函数返回值为空,我们用的主要是这个函数的副作用,依次释放每个节点内动态分配的字符串空间与该节点的动态空间。

           使用:CloseTable(   pHead    );

5.初始化配置文件

          # define MALLOC( type, len ) (type*)malloc( sizeof(type) * len )             /*malloc预定义函数*/
          # define TRUE                  1                                                                                 /* BOOL    真*/
          # define FLASE                0                                                                                 /* BOOL    假*/
          # define PRE                    15                                                                               /* 表格的前置空白数 */
          # define COL                    102                                                                             /* 表格的横向长度 */
          # define DATACOL          11                                                                              /* 表格中最最大字段数 */
 
         
a.   后三个是表格的配置,可以根据自己的需求改变其值,也可以改变OpenTable函数,使这三个配置数据做为参数传入。
          b.   表格没有列数限制,所有数据全部打印,数据量大的时候,需配置好终端。我后面会做一个有列数限制且带上下翻页的,我想这个主要问题在于缓存的设计。



6.代码

a.测试主函数
/******************************************************************************************
 *                                                                                        *
 *                                    测试主函数                                            *
 *                                                                                        *
 ******************************************************************************************/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include "DrawTable.c"

int
main( void ){

	PTABLE pHead1 = NULL,pHead2 = NULL, pHead3 = NULL;

        char *data1[10] = {
		"学号 姓名 性别 年龄 年级 班级 语文成绩 数学成绩 英语成绩 总成绩",
		"2008 王小晨 男 10 4 丙 95.5 100 98.5 294",
		"2009 张胜 男 10 4 丙 94.5 99 97.5 291",
		"2010 刘倩 女 10 4 丙 90.5 100 95.5 286",
		"2011 Mary 女 10 4 甲 99.5 100 95.5 295",
		NULL
	};
	
        char *data2[10] = {
		"编号 名称 数量 单价 产地",
		"1001011 流量计 1000 4584.3 中国广州",
		"1001012 液位计 1500 3363.6 中国湖南 aabbcc",
		"1001013 压力变送器 1200 758.9 中国上海",
		"1001014 温度变送器 2300 543.2 中国山东",
		NULL
	};

	pHead1 = OpenTable('*','-',"成绩表","共计 $ 人" ,data1 );
	PrintTable( pHead1 );
	CloseTable( pHead1 );
	pHead1 = NULL;

	pHead2 = OpenTable('*','-',"这是一张产品清单","共计 $ 种" ,data2 );
	PrintTable( pHead2 );
	CloseTable( pHead2 );
	pHead2 = NULL;

	pHead3 = OpenTable('*','-',"公共信息","共计 $ 种" ,NULL );
	PrintTable( pHead3 );
	CloseTable( pHead3 );
	pHead3 = NULL;

	
	return EXIT_SUCCESS;
}



b.制表函数库
/************************************************************************************************
 *					            						*
 *				命令行终端上画表格函数库						*
 *								            			*
 ************************************************************************************************/
/* 预处理器可以移到自己的头文件或配置中 
 * */
# define MALLOC( type, len ) (type*)malloc( sizeof(type) * len )
# define TRUE 1
# define FLASE 0
# define PRE 15  /* 表格的前置空白数 */
# define COL 102 /* 表格的横向长度 */
# define DATACOL 11 /* 表格中最最大字段数 */
/****************************************声明*************************************************/
/*  数据结构     */
typedef struct table {

	char *line;//字符串指针
	struct table *pNext;//后续节点指针

} TABLE,*PTABLE;    

/*  接口函数    */
PTABLE OpenTable(char symble1, char symble2, char *tableName, char *tableTail, char **data );//打开一张表格

void PrintTable( PTABLE pHead );//在stdout上打印一张表格

void CloseTable( PTABLE pHead );//关闭一张表格

/*  内部画图函数  */
static PTABLE CreateTable();//创建一个表格

static int DrawNull( PTABLE pHead, char symble ); //以symble字符画一条空心直线

static int DrawLine( PTABLE pHead, char symble ); //以symble字符画一条实心直线

static int DrawTitle( PTABLE pHead, char const *name, char symble );//画标题栏

static int DrawData( PTABLE pHead, char **data, char symble );//填充并统计数据,第一行为导航

static int DrawTail( PTABLE pHead, char *tableTail,int totleData, char symble);//画结尾统计行

/*  内部功能函数  */
static void AppendTable( PTABLE pHead, PTABLE new );//追加一个节点

static void CopyData( char *line, char *data, int *dataPos );// 字符串格式化copy

static void	GetDataPos(char *buffer,int *dataPos , int offset );//在数据行中定位每个数据字段

static void GetUtf8Length( char const *str, int *cnt );//utf-8编码的字符串统计

/***********************************END**********************************************/


/*********************************接口函数*******************************************/

/*
 * Function:  打开一张表格
 * symble1:   符号1,用于画表格的边框
 * symble2:   符号2,用于画表格中的分割横线
 * tableName: 表格名称,用于写入名称栏
 * tableTail: 表格统计字符串的格式
 * data:      表格中的数据,是一个字符串数组
 * return:    返回一个表指针PTABLE,如果打开失败返回NULL
 * */
PTABLE
OpenTable( char symble1, char symble2, char *tableName, char *tableTail,  char **data ){

	PTABLE pHead = NULL;

	pHead = CreateTable();//初始化一个头节点
	if( pHead != NULL ){

		int totalData = 0; //数据行统计器

		DrawLine( pHead, symble1);                           //画横线
		DrawTitle( pHead, tableName, symble2);               //写表格名
		DrawLine( pHead, symble2);                           //画横线
		totalData = DrawData( pHead, data, symble1 );        //写数据
		DrawLine( pHead, symble2);                           //画横线
		DrawTail( pHead, tableTail,totalData, symble2);      //画结尾统计
		DrawLine( pHead, symble1);                           //画横线

	}

	return pHead;

}

/*
 * Function: 在标准输出打印表格 
 * pHead:    表格指针
 * return:   void
 * */
void
PrintTable( PTABLE pHead ){

	//链表拥有头节点,头节点中无数据,故跳过
	while( pHead = pHead->pNext, pHead != NULL )
		printf( "%s\n", pHead->line );

}

/*
 * Function: 关闭一个表格( 释放所有动态分配的指针 )
 * pHead:    表格指针
 * return:   void
 * */
void
CloseTable( PTABLE pHead ){
	
	PTABLE p;

	//临时指针指向当前节点,当前节点指针前移,释放临时指针所指节点中所有的动态内存
	while( p = pHead, p != NULL){

		pHead = pHead->pNext;
		free( p->line);
		p->line = NULL;//拴野指针
		free( p );
		p = NULL;//拴野指针
	}

}
/***********************************END**********************************************/



/*********************************内部画图函数*******************************************/

/* 
 * Function:创建一个表格  (分配一个头节点) 
 * return:	PTABLE  失败则返回NULL
 * * */
static PTABLE
CreateTable(){

	PTABLE pHead;
	//动态分配一个节点
	pHead = MALLOC( TABLE , 1 );
	if( pHead != NULL){

		//该节点不包涵任何数据
		pHead->line = NULL;
		pHead->pNext = NULL;

	}

	return pHead;
}

/* function: 画一条空心直线     if( symbel == '*' )    line = "    *                          *\0" 
 * pHead:    表格指针.
 * symble:   制线符号,用symble这个字符为表格画两端.
 * return:    TRUE 画线成功, FLASE 画线失败,且释放了相应内存.
 * */
static int
DrawNull( PTABLE pHead , char symble ){

	//定义新节点空间并为其分配内存
	PTABLE new; 
	new = MALLOC( TABLE, 1 );

	if( new != NULL ){
		//为新节点分配字符串内存
		new->line = MALLOC( char, PRE+COL);// PRE 表格前的空格数, COL表格行的长度
		if( new->line != NULL ){
			//画空心直线 ( 两头有字符,中间是空格,结尾加上NUL )
			memset( new->line, 32, PRE+COL );// PRE+COL个字符全部画成空格
			memset( new->line+PRE, (int)symble, 1 );//第一个位置画上符号
			memset( new->line+PRE+COL-2, (int)symble, 1 );//倒数第二个位置画上符号
			memset( new->line+PRE+COL-1, 0 , 1 );//倒数第一个位置写入NUL,标致字符串结束
		    /*当style == '*'时  行的表达:|           *                               *\0|  */

			//追加
			new->pNext = NULL;//这步也可以放到追加函数中去
			AppendTable( pHead, new );

			return TRUE;//这是函数唯一正确的出口

		}
		//字符串内存分配失败时,释放节点的内存-----------拒绝内存泄漏,拴住野指针
		free( new );
		new = NULL; //拴住野指针
		return FLASE;

	}
	return FLASE;
}

/*
 * Function: 画一条实心直线  if(symble == '*')    line = "         *********************************\0"
 * pHead:    表格指针.
 * symble:   制表符号,用symble这个字符为表格画直线.
 * return    TRUE 画线成功, FLASE 画线失败,且释放了相应内存.
 */
static int
DrawLine( PTABLE pHead, char symble ){

	//定义新节点并分配内存空间
	PTABLE new;
	new = MALLOC( TABLE, 1 );

	if( new != NULL ){
		//分配字符指针内存空间
		new->line = MALLOC( char, PRE+COL );
		if( new->line != NULL ){
			//画出字符串
			memset( new->line, 32, PRE+COL ); //字符串清空
			memset( new->line+PRE, (int)symble, COL-1 ); //画线
			memset( new->line+PRE+COL-1, 0, 1 );//加NUL字符

			//追加节点
			new->pNext = NULL;
			AppendTable( pHead, new );

			return TRUE;
		}
		//拒绝内存泄漏,拴住野指针
		free( new );
		new=NULL;
		return FLASE;
		
	}
	return FLASE;
	/*若有不清楚之处,参考DrawNull() 函数讲解*/

}

/*
 * Function: 画标题栏     if( symble == '-') line = "        -            TABLENAME            -\0"
 * pHead:    表格指针
 * name:     标题内容指针
 * symble:   表格符号
 * return    TRUE 画线成功, FLASE 画线失败,且释放了相应内存.
 * */
static int 
DrawTitle( PTABLE pHead, char const *name, char symble ){
	//定义新节点指针并分配动态内存
	PTABLE new;
	new = MALLOC( TABLE, 1 );
	if( new != NULL ){
		//统计utf8汉字的长度
		int cnt[5];//定义字符串统计数组
		memset( cnt, 0, sizeof(int) * 5 );//清空字符串统计数组
		GetUtf8Length( name, cnt );//统计字符串中utf-8编码字符的个数。
		/* 一个汉字以utf-8编码占3个字节。
		 * 一个汉字在终端显示,占2个字符的大小。
		 * 也就是说,一个汉字在内存中占了3个字符的位置,在终端打印时却只占用2个字符的大小。
		 * 问题:英文字符串与中文字符,让其文字个数一样,但是在终端显示长度却不一样,汉字短,刚好短汉字的个数个字符。
		 * PRE+COL+cnt[3], 故分配内存时就要加上被汉字多占的字符数,也就是加上汉字的个数。
		 * */
		new->line = MALLOC( char, PRE+COL+cnt[3] );
		if( new->line != NULL ){
			//居中定位
			int len,pos;
			len = strlen( name );
			pos = ( COL - len + cnt[3] - 1 ) / 2;
			//画线
			memset( new->line, 32, PRE+COL+cnt[3] );
			memset( new->line+PRE, (int)symble, 1 );
			memcpy( new->line+PRE+pos, name, len );//把标题字符串复制到,新字符串的居中位置
			//这里还可以用 strncpy 函数, 有长度了就不要用 strcpy 函数,strcpy函数会复制 NUL字符
			memset( new->line+PRE+COL+cnt[3] - 2, (int)symble, 1 );
			memset( new->line+PRE+COL+cnt[3] - 1, 0, 1 );
			//追加
			new->pNext = NULL;
			AppendTable( pHead, new );

			return TRUE;
		}
		//拒绝内存泄漏,拴住野指针
		free( new );
		new = NULL;
		return FLASE;

	}
	return FLASE;
}

/*
 * Function:添加并统计数据
 * if( symble = '*' )   "       PTABLE:   * xxx  xxx  xxxxx  xx  xxx  xxxx *\0"
 *										  * xx   xx   xxx    xxx xx   xx   *\0"
 *                                        * xxxx x    xxxx   xx  x    xxxx *\0"
 *												.
 *											    .
 *												. 
 * pHead:   表格指针
 * data:    数据,以字符串数组存储的数据。
 * symble:  制表符号
 * return:  统计的数据数,以行为单位.
 * */
static int 
DrawData( PTABLE pHead, char **data, char symble ){

	int totalData = 0; // 数据计数器

	//用导航计算每个字段的定位点,整张表每条数据的每个字段的定位点都一样
	int dataPos[DATACOL];//定位点数组, DATACOL为最大字段数
	char buffer[COL];// strtok会破坏原字符串,所以要用一个缓存来解决这个问题
	if( data != NULL && *data != NULL){//数据不为空

		strcpy( buffer, *data );//数据写入缓存
		GetDataPos( buffer, dataPos, 3 );//获取字段定位点数据
		dataPos[1] += 1;//第一个字段定位点要存放制表符号,所以定位点得右移,让出这个位置

	}else{

		DrawNull( pHead,symble );
		DrawNull( pHead,symble );
		DrawTitle( pHead,"您还没有添加数据呢^_^",symble );
		DrawNull( pHead,symble );
		DrawNull( pHead,symble );
		return  totalData;

	}

	//循环追加数据行
	while( data != NULL && *data != NULL ){

		//定义新节点指针并分配动态内存
		PTABLE new = NULL;
		new = MALLOC( TABLE, 1 );
		if( new != NULL ){
			//统计汉字数量
			int cnt[5];
			memset( cnt, 0, sizeof(int) * 5 );
			GetUtf8Length( *data, cnt );
			//为字符串分配动态内存
			new->line = MALLOC( char, PRE + COL + cnt[3]);//DrawTitle函数中的有详解
			if( new->line != NULL ){
				//画数据行
				memset( new->line, 32, PRE+COL+cnt[3] );
				memset( new->line+PRE, (int)symble, 1 );
				strcpy( buffer, *data);// strtok会破坏原字符串,所以要用一个缓存来解决这个问题
				// 在每个字段定位点上,写入每个字段
				CopyData( new->line, buffer, dataPos );
				memset( new->line+PRE+COL+cnt[3]-2, (int)symble, 1 );
				memset( new->line+PRE+COL+cnt[3]-1, 0, 1 );
				//追加
				new->pNext = NULL;
				AppendTable( pHead, new );

				data++;//指向下一个字符串指针。
				totalData++;//统计加1
				continue;

			}
			free( new );
			new = NULL;
			continue;
		}
		continue;
	}

	return --totalData;//导航栏纳入统计

}

/* Function:  画结尾统计行  if( strcmp( tableTail, "共计 $ 人")) 
 *                                line = "  *          共计 totalData 人   *\0";
 * pHead:     表格指针
 * tableTail: 统计风格
 * totalData: 数据统计个数
 * symble:    制表符号
 * return    TRUE 画线成功, FLASE 画线失败,且释放了相应内存.
 * */
static int 
DrawTail( PTABLE pHead, char *tableTail, int totalData, char symble){

	//将整数保存为字符串并计算长度
	char str[5];
	int numLen;
	sprintf( str, "%d", totalData );
	numLen = strlen( str );
	
	//以$分解tableTail为2个字符串并计算各长度
	char pre[100], tail[100];
	int lenP, lenT;
	sscanf( tableTail, "%s $ %s", pre, tail );
	lenP = strlen( pre );
	lenT = strlen( tail );

	//tableTail的汉字统计
	int cnt[5];
	memset( cnt, 0, sizeof(int) * 5 );
	GetUtf8Length( tableTail, cnt);
	
	//定义新节点指针并分配动态内存
	PTABLE new;
	new = MALLOC( TABLE, 1 );
	if( new != NULL ){

		//为字符串分配动态内存
		new->line = MALLOC( char, (PRE+COL+cnt[3]) );
		if( new->line != NULL){
			//画统计行
			memset( new->line, 32, (PRE+COL+cnt[3]) );
			memset( new->line+PRE,(int)symble, 1 );
			memcpy( new->line+PRE+COL-18,pre, lenP );
			memcpy( new->line+PRE+COL-18+lenP+2,str, numLen );
			memcpy( new->line+PRE+COL-18+lenP+numLen+4,tail, lenT );
			memset( new->line+PRE+COL+cnt[3]-2,(int)symble, 1 );
			memset( new->line+PRE+COL+cnt[3]-1,0, 1 );

			//追加数据
			new->pNext = NULL;
			AppendTable( pHead, new );

			return TRUE;

		}
		//拒绝内存泄漏,拴住野指针
		free( new );
		return FLASE;
	}

	return FLASE;
}

/**************************************内部功能函数 *****************************************/

/* Function:追加一个节点 
 * phead:   表格指针
 * new:     新的节点指针
 * return   void
 * */
static void
AppendTable( PTABLE pHead , PTABLE new ){
	
	//寻找表格的最后一个节点
	while( pHead->pNext != NULL )
		pHead = pHead->pNext;

	pHead->pNext = new;
	//注: new->pNext = NULL 这向工作在创建new节点时完成。

	return;
}

/*
 * Function: 分配插入位置
 * buffer:   导航字符串指针 
 * dataPos:  统计位置数组指针
 * offset:   数据写入时的向右偏移量  如*data 偏移0个字节,* data 偏移1个字节,*  data偏移2个字节.... 
 * return    void
 * */
static void	
GetDataPos(char *buffer,int *dataPos, int offset ){

	//以 token 里的字符分解字符串 buffer, 统计字段数量
	int i;
	char *tmp;
	char token[] = "/ ,!?|-";
	for( i=0, tmp = strtok( buffer, token ); tmp !=NULL && i < DATACOL-1; tmp = strtok( NULL, token) )
		i++; 
	
	dataPos[0] = i;//dataPos[1] 存放字段数量, dataPos[1]存放第一个字段的定位,dataPos[2].....
	
	//将ave平分i份,得到每份的长度
	int ave;
	ave = COL / i; //数据行的长度平分给i个字段,由于不一点完全整除,可能最后一个会长一点。

	//所有字段定位写入
	for( i = 1; i <= dataPos[0]; i++ )
		dataPos[i] = PRE + ave * (i-1) + offset;
	//  该字段位置 = 前置空白 + 平均值 * 第几个字段 + 偏移量  

	return;

}

/*
 * Function: 将数据写入表格已分配了好的空间
 * *line:    已分配好的字符串空间
 * *data:    被写入的数据
 * *dataPos: 每行所有字段的定位
 * return:   void
 * */
void
CopyData( char *line, char *data, int *dataPos ){

	//分解数据字符串,将其写入subData字符指针数组
	char *subData[DATACOL];//字段(字符)数组
	char token[] = " ,/!?";
	int i;//字段计数器

	for( i=0, subData[i] = strtok( data, token); i < dataPos[0] && subData[i] != NULL; 
			subData[i] = strtok(NULL,token) )
		i++;
	//subData数组必须以NULL结尾
	if( subData[i] != NULL )
		subData[i] = NULL;//字符串指针数组以null结尾

	//统计本条数据中,每个字段中文的个数,存放在pcnt数组中
	int pcnt[DATACOL];
	int cnt[5];
	memset( pcnt, 0, sizeof(int) * DATACOL );//置0
	for( i = 1; i <= dataPos[0]; i++ ){// pcnt 与 dataPos 一致,数据从 1 开始写
		cnt[3] = 0;//汉字计数器清零
		GetUtf8Length( subData[i-1], cnt );
		pcnt[i] = cnt[3];
	}
	pcnt[0] = 0;//由于pcnt用于加法运算,写上这一行更安全。
	
	//数据写入
	int j, pos, len;
	for( i = 1; i <= dataPos[0]; i++ ){
		//数据行中,有了汉字后,计算其实际定位
		for( j = i - 1, pos = 0; j > 0; j-- )
			pos +=pcnt[j];//当前字段前面所有字段中汉字的总和

	    len = strlen( subData[i-1] );
		strncpy( line+dataPos[i]+pos, subData[i-1], len );//复制数据

	}

	return;
}

/*
 * Function: utf-8字符串统计函数
 * str:      字符串指针 
 * cnt:      统计数组指针
 * return    void
 * */
static void 
GetUtf8Length( char const *str, int *cnt ){
	
	//memset( cnt, 0 ,sizeof(int) * 5 );
	//我的其它博文中有讲解
	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;/* 11110xxx*/
						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;
	}
}

/********************************************END*****************************************/
/***********************************解除预定义, 让项目更安全*********************************/
# undef MALLOC 
# undef TURE 
# undef FLASE 
# undef PRE 
# undef COL 
# undef DATACOL  
/**************************************END OF FILE***************************************/



  Writer:  Anden       Email:  andensemail@163.com      Time:  2016.04.04

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值